Skip to content

Commit

Permalink
Fix loading of DDFs due constants.json race (#7793)
Browse files Browse the repository at this point in the history
Stupid beginner mistake. The JSON files are read in arbitrary file system order. Which is ok except for the constants.json which need to be read first in order to determine if a DDF should be loaded.
  • Loading branch information
manup authored May 28, 2024
1 parent b303fea commit 09ec300
Showing 1 changed file with 41 additions and 11 deletions.
52 changes: 41 additions & 11 deletions device_descriptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1083,13 +1083,14 @@ const DeviceDescription &DeviceDescriptions::get(const Resource *resource, DDF_M

if (modelidAtomIndex == 0 || mfnameAtomIndex == 0)
{
return d->invalidDescription; // should not happen
U_ASSERT(modelidItem->toString().isEmpty());
U_ASSERT(mfnameItem->toString().isEmpty());
return d->invalidDescription; // happens when called from legacy init code addLightNode() etc.
}

U_ASSERT(modelidAtomIndex != 0);
U_ASSERT(mfnameAtomIndex != 0);


/*
* Filter matching DDFs, there can be multiple entries for the same modelid and manufacturer name.
* Further sorting for the 'best' match according to attr/ddf_policy is done afterwards.
Expand Down Expand Up @@ -1172,7 +1173,14 @@ const DeviceDescription &DeviceDescriptions::get(const Resource *resource, DDF_M

if (ddf1.storageLocation == deCONZ::DdfLocation || ddf1.storageLocation == deCONZ::DdfUserLocation)
{
rawJsonIndex = matchedIndices[i];
if (rawJsonIndex == invalidIndex)
{
rawJsonIndex = matchedIndices[i];
}
else if (d->descriptions[rawJsonIndex].status == QLatin1String("Draft"))
{
rawJsonIndex = matchedIndices[i];
}
continue;
}

Expand Down Expand Up @@ -1997,6 +2005,35 @@ void DeviceDescriptions::readAllRawJson()

std::array<deCONZ::StorageLocation, 2> locations = { deCONZ::DdfLocation, deCONZ::DdfUserLocation};

bool hasConstants = false;

// need to resolve constants first
for (size_t dit = 0; dit < locations.size(); dit++)
{
const QString filePath = deCONZ::getStorageLocation(locations[dit]) + "/generic/constants.json";

pctx->filePath[0] = '\0';
pctx->filePathLength = 0;
pctx->scratchPos = 0;

{
U_SStream ss;
U_sstream_init(&ss, pctx->filePath, sizeof(pctx->filePath));
U_sstream_put_str(&ss, filePath.toUtf8().data());
pctx->filePathLength = ss.pos;
}

if (DDF_ReadFileInMemory(pctx))
{
if (DDF_ReadConstantsJson(pctx, d->constants2))
{
hasConstants = true;
}
}
}

U_ASSERT(hasConstants);

for (size_t dit = 0; dit < locations.size(); dit++)
{
const QString dirpath = deCONZ::getStorageLocation(locations[dit]);
Expand All @@ -2019,13 +2056,6 @@ void DeviceDescriptions::readAllRawJson()

if (it.filePath().endsWith(QLatin1String("generic/constants.json")))
{
if (DDF_ReadFileInMemory(pctx))
{
if (DDF_ReadConstantsJson(pctx, d->constants2))
{

}
}
}
else if (it.fileName() == QLatin1String("button_maps.json"))
{ }
Expand Down Expand Up @@ -2836,7 +2866,7 @@ void DeviceDescriptions::handleDDFInitRequest(const Event &event)

if (result >= 0)
{
DBG_Printf(DBG_INFO, "DEV found DDF for " FMT_MAC ", path: %s\n", FMT_MAC_CAST(event.deviceKey()), qPrintable(ddf.path));
DBG_Printf(DBG_INFO, "DEV found DDF for " FMT_MAC ", path: %s, result: %d\n", FMT_MAC_CAST(event.deviceKey()), qPrintable(ddf.path), result);
}

if (result == 0)
Expand Down

0 comments on commit 09ec300

Please sign in to comment.