Skip to content

Commit

Permalink
Fix adding fabricindex to LocationDirectory
Browse files Browse the repository at this point in the history
  • Loading branch information
tehampson committed Aug 15, 2024
1 parent 40b09c3 commit 7105196
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -215,40 +215,28 @@ EcosystemLocationStruct::Builder::SetLocationDescriptorLastEdit(uint64_t aLocati
return *this;
}

EcosystemLocationStruct::Builder & EcosystemLocationStruct::Builder::SetFabricIndex(FabricIndex aFabricIndex)
{
VerifyOrDie(!mIsAlreadyBuilt);
mFabricIndex = aFabricIndex;
return *this;
}


std::unique_ptr<EcosystemLocationStruct> EcosystemLocationStruct::Builder::Build()
{
VerifyOrReturnValue(!mIsAlreadyBuilt, nullptr, ChipLogError(Zcl, "Build() already called"));
VerifyOrReturnValue(!mLocationDescriptor.mLocationName.empty(), nullptr, ChipLogError(Zcl, "Must Provided Location Name"));
VerifyOrReturnValue(mLocationDescriptor.mLocationName.size() <= kLocationDescriptorNameMaxSize, nullptr,
ChipLogError(Zcl, "Must Location Name must be less than 64 bytes"));
VerifyOrReturnValue(mFabricIndex >= kMinValidFabricIndex, nullptr, ChipLogError(Zcl, "Fabric index is invalid"));
VerifyOrReturnValue(mFabricIndex <= kMaxValidFabricIndex, nullptr, ChipLogError(Zcl, "Fabric index is invalid"));

// std::make_unique does not have access to private constructor we workaround with using new
std::unique_ptr<EcosystemLocationStruct> ret{ new EcosystemLocationStruct(std::move(mLocationDescriptor),
mLocationDescriptorLastEditEpochUs,
mFabricIndex) };
mLocationDescriptorLastEditEpochUs) };
mIsAlreadyBuilt = true;
return ret;
}

CHIP_ERROR EcosystemLocationStruct::Encode(const AttributeValueEncoder::ListEncodeHelper & aEncoder,
const std::string & aUniqueLocationId)
const EcosystemLocationIdentifier & aUniqueLocationId)
{
Structs::EcosystemLocationStruct::Type locationStruct;
VerifyOrDie(!aUniqueLocationId.empty());
locationStruct.uniqueLocationID = CharSpan(aUniqueLocationId.c_str(), aUniqueLocationId.size());
locationStruct.uniqueLocationID = CharSpan(aUniqueLocationId.mUniqueLocationId.c_str(), aUniqueLocationId.mUniqueLocationId.size());
locationStruct.locationDescriptor = GetEncodableLocationDescriptorStruct(mLocationDescriptor);
locationStruct.locationDescriptorLastEdit = mLocationDescriptorLastEditEpochUs;
locationStruct.SetFabricIndex(mFabricIndex);
locationStruct.SetFabricIndex(aUniqueLocationId.mFabricIndex);

return aEncoder.Encode(locationStruct);
}
Expand Down Expand Up @@ -283,16 +271,22 @@ CHIP_ERROR EcosystemInformationServer::AddDeviceInfo(EndpointId aEndpoint, std::
}

CHIP_ERROR EcosystemInformationServer::AddLocationInfo(EndpointId aEndpoint, const std::string & aLocationId,
FabricIndex aFabricIndex,
std::unique_ptr<EcosystemLocationStruct> aLocation)
{
VerifyOrReturnError(aLocation, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError((aEndpoint != kRootEndpointId && aEndpoint != kInvalidEndpointId), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(!aLocationId.empty(), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(aFabricIndex >= kMinValidFabricIndex, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(aFabricIndex <= kMaxValidFabricIndex, CHIP_ERROR_INVALID_ARGUMENT);

auto & deviceInfo = mDevicesMap[aEndpoint];
VerifyOrReturnError((deviceInfo.mLocationDirectory.find(aLocationId) == deviceInfo.mLocationDirectory.end()),
// TODO rename foobar
EcosystemLocationIdentifier foobar = {.mUniqueLocationId=aLocationId, .mFabricIndex=aFabricIndex};
VerifyOrReturnError((deviceInfo.mLocationDirectory.find(foobar) == deviceInfo.mLocationDirectory.end()),
CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError((deviceInfo.mLocationDirectory.size() < kLocationDirectoryMaxSize), CHIP_ERROR_NO_MEMORY);
deviceInfo.mLocationDirectory[aLocationId] = std::move(aLocation);
deviceInfo.mLocationDirectory[foobar] = std::move(aLocation);
return CHIP_NO_ERROR;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ struct LocationDescriptorStruct
std::optional<Globals::AreaTypeTag> mAreaType;
};

struct EcosystemLocationIdentifier {
bool operator<(const EcosystemLocationIdentifier& other) const {
return mUniqueLocationId < other.mUniqueLocationId || (mUniqueLocationId == other.mUniqueLocationId && mFabricIndex < other.mFabricIndex);
}
std::string mUniqueLocationId;
FabricIndex mFabricIndex;
};

// This intentionally mirrors Structs::EcosystemLocationStruct::Type but has ownership
// of underlying types.
class EcosystemLocationStruct
Expand All @@ -115,7 +123,6 @@ class EcosystemLocationStruct
Builder & SetFloorNumber(std::optional<int16_t> aFloorNumber);
Builder & SetAreaTypeTag(std::optional<Globals::AreaTypeTag> aAreaTypeTag);
Builder & SetLocationDescriptorLastEdit(uint64_t aLocationDescriptorLastEditEpochUs);
Builder & SetFabricIndex(FabricIndex aFabricIndex);

// Upon success this object will have moved all ownership of underlying
// types to EcosystemDeviceStruct and should not be used afterwards.
Expand All @@ -124,25 +131,23 @@ class EcosystemLocationStruct
private:
LocationDescriptorStruct mLocationDescriptor;
uint64_t mLocationDescriptorLastEditEpochUs = 0;
FabricIndex mFabricIndex = kUndefinedFabricIndex;
bool mIsAlreadyBuilt = false;
};

CHIP_ERROR Encode(const AttributeValueEncoder::ListEncodeHelper & aEncoder, const std::string & aUniqueLocationId);
CHIP_ERROR Encode(const AttributeValueEncoder::ListEncodeHelper & aEncoder, const EcosystemLocationIdentifier & aUniqueLocationId);

private:
// Constructor is intentionally private. This is to ensure that it is only constructed with
// values that conform to the spec.
explicit EcosystemLocationStruct(LocationDescriptorStruct && aLocationDescriptor, uint64_t aLocationDescriptorLastEditEpochUs, FabricIndex aFabricIndex) :
mLocationDescriptor(aLocationDescriptor), mLocationDescriptorLastEditEpochUs(aLocationDescriptorLastEditEpochUs), mFabricIndex(aFabricIndex)
explicit EcosystemLocationStruct(LocationDescriptorStruct && aLocationDescriptor, uint64_t aLocationDescriptorLastEditEpochUs) :
mLocationDescriptor(aLocationDescriptor), mLocationDescriptorLastEditEpochUs(aLocationDescriptorLastEditEpochUs)
{}
// EcosystemLocationStruct is used as a value in a key-value map.
// Because UniqueLocationId is manditory when an entry exist, and
// it is unique, we use it as a key to the key-value pair and is why it is
// Because UniqueLocationId and FabricIndex are manditory when an entry exist,
// and needs to be unique, we use it as a key to the key-value pair and is why it is
// not explicitly in this struct.
LocationDescriptorStruct mLocationDescriptor;
uint64_t mLocationDescriptorLastEditEpochUs;
FabricIndex mFabricIndex;
};

class EcosystemInformationServer
Expand Down Expand Up @@ -186,7 +191,7 @@ class EcosystemInformationServer
* @return #CHIP_NO_ERROR on success.
* @return Other CHIP_ERROR associated with issue.
*/
CHIP_ERROR AddLocationInfo(EndpointId aEndpoint, const std::string & aLocationId,
CHIP_ERROR AddLocationInfo(EndpointId aEndpoint, const std::string & aLocationId, FabricIndex aFabricIndex,
std::unique_ptr<EcosystemLocationStruct> aLocation);

/**
Expand All @@ -207,8 +212,7 @@ class EcosystemInformationServer
{
Optional<uint64_t> mRemovedOn = NullOptional;
std::vector<std::unique_ptr<EcosystemDeviceStruct>> mDeviceDirectory;
// Map key is using the UniqueLocationId
std::map<std::string, std::unique_ptr<EcosystemLocationStruct>> mLocationDirectory;
std::map<EcosystemLocationIdentifier, std::unique_ptr<EcosystemLocationStruct>> mLocationDirectory;
};

CHIP_ERROR EncodeRemovedOnAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder);
Expand Down

0 comments on commit 7105196

Please sign in to comment.