Skip to content

Commit

Permalink
handling global attributes per cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
paulr34 committed Oct 4, 2023
1 parent 69accf8 commit 879713a
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 21 deletions.
17 changes: 17 additions & 0 deletions src-electron/db/query-cluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@
const dbApi = require('./db-api.js')
const dbMapping = require('./db-mapping.js')

/**
* Returns a cluster name from the cluster ref
*
* @param db
* @param clusterRef
* @returns Cluster name
*/
async function selectClusterName(db, clusterRef) {
let clusterName = await dbApi.dbAll(
db,
'SELECT NAME FROM CLUSTER WHERE CLUSTER_ID = ?',
[clusterRef]
)
return clusterName[0].NAME
}

/**
* All cluster details along with their attribute details per endpoint.
* @param db
Expand Down Expand Up @@ -280,6 +296,7 @@ async function selectTokenAttributeClustersForEndpoint(
return rows.map(dbMapping.map.cluster)
}

exports.selectClusterName = selectClusterName
exports.selectClusterDetailsFromEnabledClusters =
selectClusterDetailsFromEnabledClusters
exports.selectAllUserClustersWithTokenAttributes =
Expand Down
23 changes: 13 additions & 10 deletions src-electron/db/query-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const dbMapping = require('./db-mapping.js')
const queryPackage = require('./query-package.js')
const dbEnum = require('../../src-shared/db-enum.js')
const queryZcl = require('./query-zcl.js')
const queryUpgrade = require('../upgrade/upgrade.js')
const queryDeviceType = require('./query-device-type')
const queryCommand = require('./query-command.js')
const restApi = require('../../src-shared/rest-api.js')
Expand Down Expand Up @@ -211,15 +212,17 @@ async function insertOrUpdateAttributeState(
attributeId,
clusterRef
)
if (
staticAttribute.storagePolicy ==
dbEnum.storagePolicy.attributeAccessInterface
) {
staticAttribute.storagePolicy = dbEnum.storageOption.external
} else {
staticAttribute.storagePolicy = dbEnum.storageOption.ram
}

let forcedExternal = await queryUpgrade.getForcedExternalStorage(
db,
attributeId
)
let storageOption = await queryUpgrade.computeStorageNewConfig(
db,
clusterRef,
staticAttribute.storagePolicy,
forcedExternal,
staticAttribute.name
)
if (staticAttribute == null) {
throw new Error(`COULD NOT LOCATE ATTRIBUTE: ${attributeId} `)
}
Expand Down Expand Up @@ -253,7 +256,7 @@ INTO ENDPOINT_TYPE_ATTRIBUTE (
cluster.endpointTypeClusterId,
attributeId,
staticAttribute.defaultValue ? staticAttribute.defaultValue : '',
staticAttribute.storagePolicy,
storageOption,
clusterRef,
reportMinInterval,
reportMaxInterval,
Expand Down
27 changes: 23 additions & 4 deletions src-electron/db/query-impexp.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
const dbApi = require('./db-api')
const dbEnums = require('../../src-shared/db-enum')
const dbMapping = require('./db-mapping.js')

const queryUpgrade = require('../upgrade/upgrade.js')
/**
* Imports a single endpoint
* @param {} db
Expand Down Expand Up @@ -619,20 +619,23 @@ ORDER BY
* @param {*} endpointTypeId
* @param {*} endpointClusterId may be null if global attribute
* @param {*} attribute
* @param {*} cluster
* @returns Promise of an attribute insertion.
*/
async function importAttributeForEndpointType(
db,
packageIds,
endpointTypeId,
endpointClusterId,
attribute
attribute,
cluster
) {
let selectAttributeQuery = `
SELECT
A.ATTRIBUTE_ID,
A.REPORTING_POLICY,
A.STORAGE_POLICY
A.STORAGE_POLICY,
A.NAME
FROM
ATTRIBUTE AS A
INNER JOIN
Expand All @@ -657,14 +660,18 @@ WHERE
let attributeId
let reportingPolicy
let storagePolicy
let forcedExternal
let attributeName
if (atRow.length == 0) {
attributeId = null
reportingPolicy = null
storagePolicy = null
attributeName = null
} else {
attributeId = atRow[0].ATTRIBUTE_ID
reportingPolicy = atRow[0].REPORTING_POLICY
storagePolicy = atRow[0].STORAGE_POLICY
attributeName = atRow[0].NAME
}

// If the spec has meanwhile changed the policies to mandatory or prohibited,
Expand All @@ -674,7 +681,19 @@ WHERE
} else if (reportingPolicy == dbEnums.reportingPolicy.prohibited) {
attribute.reportable = false
}

if (attributeId) {
forcedExternal = await queryUpgrade.getForcedExternalStorage(
db,
attributeId
)
storagePolicy = await queryUpgrade.computeStorageImport(
db,
cluster.name,
storagePolicy,
forcedExternal,
attributeName
)
}
if (storagePolicy == dbEnums.storagePolicy.attributeAccessInterface) {
attribute.storageOption = dbEnums.storageOption.external
}
Expand Down
17 changes: 17 additions & 0 deletions src-electron/db/query-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,22 @@ async function getPackageByPackageId(db, packageId) {
.then(dbMapping.map.package)
}

/**
* Returns a package ref from the attribute ID
*
* @param db
* @param attributeId
* @returns package ref
*/
async function getPackageRefByAttributeId(db, attributeId) {
let package_ref = await dbApi.dbAll(
db,
'SELECT PACKAGE_REF FROM ATTRIBUTE WHERE ATTRIBUTE_ID = ?',
[attributeId]
)
return package_ref[0].PACKAGE_REF
}

/**
* Resolves with a CRC or null for a given path.
*
Expand Down Expand Up @@ -979,6 +995,7 @@ async function insertSessionKeyValuesFromPackageDefaults(db, sessionId) {
}

// exports
exports.getPackageRefByAttributeId = getPackageRefByAttributeId
exports.getPackageByPathAndParent = getPackageByPathAndParent
exports.getPackageByPackageId = getPackageByPackageId
exports.getPackagesByType = getPackagesByType
Expand Down
3 changes: 2 additions & 1 deletion src-electron/importexport/import-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ async function importEndpointTypes(
allZclPackageIds,
endpointId,
endpointClusterId,
attribute
attribute,
cluster
)
)
})
Expand Down
121 changes: 121 additions & 0 deletions src-electron/upgrade/upgrade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**
*
* Copyright (c) 2020 Silicon Labs
*
* 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.
*/

const dbApi = require('../db/db-api.js')
const queryPackage = require('../db/query-package.js')
const queryCluster = require('../db/query-cluster.js')
const dbEnum = require('../../src-shared/db-enum.js')
const fs = require('fs')
const fsp = fs.promises

/**
* This file implements upgrade rules which are used to upgrade .zap files and xml files
* to be in sync with the spec
*/

/**
* Returns an array of objects containing global attributes that should be forced external.
*
* @export
* @param {*} db
* @param {*} attributeId
* @returns An array of objects
*/

async function getForcedExternalStorage(db, attributeId) {
let pkgs = await queryPackage.getPackageRefByAttributeId(db, attributeId)
let zcl = await queryPackage.getPackageByPackageId(db, pkgs)
zcl = zcl.path
let obj = await fsp.readFile(zcl)
let data = JSON.parse(obj)
let byName = data?.attributeAccessInterfaceAttributes
let lists = data?.listsUseAttributeAccessInterface
let forcedExternal = { byName, lists }
return forcedExternal
}

/**
* Returns a flag stating which type of storage option the attribute is categorized to be.
*
* @export
* @param {*} db
* @param {*} clusterName
* @param {*} clusterRef
* @param {*} storagePolicy
* @param {*} forcedExternal
* @param {*} attributeId
* @returns Storage Option
*/

async function computeStorageNewConfig(
db,
clusterRef,
storagePolicy,
forcedExternal,
attributeName
) {
let storageOption
let clusterName
clusterName = await queryCluster.selectClusterName(db, clusterRef)
if (storagePolicy == dbEnum.storagePolicy.attributeAccessInterface) {
storageOption = dbEnum.storageOption.external
} else if (storagePolicy == dbEnum.storagePolicy.any) {
storageOption = dbEnum.storageOption.ram
} else {
throw 'check storage policy'
}
if (
forcedExternal.byName &&
forcedExternal.byName[clusterName] &&
forcedExternal.byName[clusterName].includes(attributeName)
) {
storageOption = dbEnum.storageOption.external
}
return storageOption
}

/**
* Returns a flag stating which type of storage option the attribute is categorized to be.
*
* @export
* @param {*} db
* @param {*} clusterName
* @param {*} forcedExternal
* @param {*} attributeId
* @returns Storage Policy
*/

async function computeStorageImport(
db,
clusterName,
storagePolicy,
forcedExternal,
attributeName
) {
if (
forcedExternal.byName &&
forcedExternal.byName[clusterName] &&
forcedExternal.byName[clusterName].includes(attributeName)
) {
storagePolicy = dbEnum.storagePolicy.attributeAccessInterface
}
return storagePolicy
}

exports.getForcedExternalStorage = getForcedExternalStorage
exports.computeStorageImport = computeStorageImport
exports.computeStorageNewConfig = computeStorageNewConfig
1 change: 0 additions & 1 deletion src-electron/zcl/zcl-loader-silabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,6 @@ function prepareCluster(cluster, context, isExtension = false) {
if (context.listsUseAttributeAccessInterface && attribute.$.entryType) {
storagePolicy = dbEnum.storagePolicy.attributeAccessInterface
} else if (
context.listsUseAttributeAccessInterface &&
context.attributeAccessInterfaceAttributes &&
context.attributeAccessInterfaceAttributes[cluster.name] &&
context.attributeAccessInterfaceAttributes[cluster.name].includes(name)
Expand Down
4 changes: 2 additions & 2 deletions test/gen-matter-4.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ test(
},\\`)

expect(ept).toContain(`#define GENERATED_ENDPOINT_TYPES { \\
{ ZAP_CLUSTER_INDEX(0), 29, 377 }, \\
{ ZAP_CLUSTER_INDEX(0), 29, 367 }, \\
{ ZAP_CLUSTER_INDEX(29), 46, 3516 }, \\
{ ZAP_CLUSTER_INDEX(75), 5, 105 }, \\
{ ZAP_CLUSTER_INDEX(80), 1, 0 }, \\
Expand Down Expand Up @@ -150,7 +150,7 @@ test(
expect(ept).toContain('#define GENERATED_CLUSTER_COUNT 81')
expect(ept).toContain('#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 79')
expect(ept).toContain('#define ATTRIBUTE_SINGLETONS_SIZE (37)')
expect(ept).toContain('#define ATTRIBUTE_MAX_SIZE (3998)')
expect(ept).toContain('#define ATTRIBUTE_MAX_SIZE (3988)')
expect(ept).toContain('#define FIXED_ENDPOINT_COUNT (4)')
expect(ept).toContain(
'#define FIXED_ENDPOINT_ARRAY { 0x0000, 0x0001, 0x0002, 0xFFFE }'
Expand Down
6 changes: 3 additions & 3 deletions test/tokens.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ beforeAll(async () => {
env.zapVersion()
)
await zclLoader.loadZcl(db, env.builtinSilabsZclMetafile())
}, testUtil.timeout.medium())
}, testUtil.timeout.long())

afterAll(() => dbApi.closeDatabase(db), testUtil.timeout.short())

Expand All @@ -58,7 +58,7 @@ test(
expect(context.packageId).not.toBeNull()
templateContext = context
},
testUtil.timeout.medium()
testUtil.timeout.long()
)

test(
Expand All @@ -68,7 +68,7 @@ test(
templateContext.sessionId = importResult.sessionId
expect(importResult.sessionId).not.toBeNull()
},
testUtil.timeout.medium()
testUtil.timeout.long()
)

test(
Expand Down

0 comments on commit 879713a

Please sign in to comment.