Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the ZAP template to encode/decode commands #3935

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -232,5 +232,9 @@ TabWidth: 8
UseTab: Never
---
Language: JavaScript
BasedOnStyle: WebKit
AlignConsecutiveAssignments: true
AllowShortFunctionsOnASingleLine: None
IndentWidth: 2
ColumnLimit: 132
...
6 changes: 1 addition & 5 deletions src/app/zap-templates/af-structs.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,12 @@ typedef struct _{{asType label}} {
{{ident}}chip::EndpointId {{asSymbol label}};
{{else if (isStrEqual label "endpointId")}}
{{ident}}chip::EndpointId {{asSymbol label}};
{{else if (isStrEqual type "CLUSTER_ID")}}
{{ident}}chip::ClusterId {{asSymbol label}};
{{else if (isStrEqual type "ATTRIBUTE_ID")}}
{{ident}}chip::AttributeId {{asSymbol label}};
{{else if (isStrEqual label "groupId")}}
{{ident}}chip::GroupId {{asSymbol label}};
{{else if (isStrEqual label "commandId")}}
{{ident}}chip::CommandId {{asSymbol label}};
{{else}}
{{ident}}{{asUnderlyingType type}} {{asSymbol label}};
{{ident}}{{asUnderlyingZclType type}} {{asSymbol label}};
{{/if}}
{{/zcl_struct_items}}
} {{asUnderlyingType label}};
Expand Down
2 changes: 1 addition & 1 deletion src/app/zap-templates/attribute-size.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
// ZCL attribute sizes
{{#zcl_atomics}}
{{#if size}}
{{ident}}ZCL_{{asDelimitedMacro name}}_ATTRIBUTE_TYPE, {{size}}, \
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
{{ident}}ZCL_{{asDelimitedMacro name}}_ATTRIBUTE_TYPE, {{size}},
{{/if}}
{{/zcl_atomics}}
41 changes: 33 additions & 8 deletions src/app/zap-templates/call-command-handler-src.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,43 @@ EmberAfStatus emberAf{{asCamelCased name false}}Cluster{{asCamelCased side false
{{#if (isCommandAvailable parent.side incoming outgoing commandSource name)}}
case ZCL_{{asDelimitedMacro name}}_COMMAND_ID: {
{{#if (zcl_command_arguments_count this.id)}}
uint32_t argOffset = 0;
uint32_t payloadOffset = cmd->payloadStartIndex;
{{#zcl_command_arguments}}
{{asUnderlyingType type}} * {{asSymbol label}} = ({{asUnderlyingType type}} *)(cmd->buffer + argOffset);
{{#unless (isLastElement index count)}}
argOffset+= sizeof({{asUnderlyingType type}});
{{/unless}}
{{asUnderlyingZclType type}} {{asSymbol label}};
{{/zcl_command_arguments}}

{{#zcl_command_arguments}}
{{#if presentIf}}
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
if ({{presentIf}})
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
{
{{/if}}
{{#if isArray}}
{{asSymbol label}} = cmd->buffer + payloadOffset;
{{else}}
if (cmd->bufLen < payloadOffset + {{asReadTypeLength type}})
{
return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
}
{{asSymbol label}} = emberAfGet{{asReadType type}}(cmd->buffer, payloadOffset, cmd->bufLen);
{{#unless (isLastElement index count)}}
{{#if (isString type)}}
payloadOffset += emberAf{{asReadType type}}Length({{asSymbol label}}) + {{asReadTypeLength type}};
{{else}}
payloadOffset += {{asReadTypeLength type}};
{{/if}}
{{/unless}}
{{/if}}
{{#if presentIf}}
}
else
{
{{asSymbol label}} = {{asValueIfNotPresent type}};
}
{{/if}}
{{/zcl_command_arguments}}

wasHandled = emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback({{#zcl_command_arguments}} *{{asSymbol label}}{{#unless (isLastElement index count)}}, {{/unless}}{{/zcl_command_arguments}});
{{else}}
wasHandled = emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback();
{{/if}}
wasHandled = emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback({{#zcl_command_arguments}}{{asSymbol label}}{{#unless (isLastElement index count)}}, {{/unless}}{{/zcl_command_arguments}});
break;
}
{{/if}}
Expand Down
7 changes: 1 addition & 6 deletions src/app/zap-templates/callback.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,7 @@ void emberAf{{asCamelCased name false}}Cluster{{asCamelCased side false}}TickCal
{{/if}}
*/

{{#if (zcl_command_arguments_count this.id)}}
bool emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback({{#zcl_command_arguments}} {{asUnderlyingType type}} {{asSymbol label}}{{#unless (isLastElement index count)}}, {{/unless}}{{/zcl_command_arguments}});
{{else}}
bool emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback();
{{/if}}

bool emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback({{#zcl_command_arguments}}{{asUnderlyingZclType type}} {{asSymbol label}}{{#unless (isLastElement index count)}}, {{/unless}}{{/zcl_command_arguments}});

{{/if}}
{{/if}}
Expand Down
1 change: 1 addition & 0 deletions src/app/zap-templates/chip-templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "CHIP templates",
"version": "chip-v1",
"helpers": ["helper-chip.js"],
"override": "override.js",
"templates": [
{
"path": "af-structs.zapt",
Expand Down
158 changes: 137 additions & 21 deletions src/app/zap-templates/helper-chip.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,20 @@
* @module Templating API: toplevel utility helpers
*/

// Import Zcl helper from zap core
const helperZcl = require('../../../third_party/zap/repo/src-electron/generator/helper-zcl.js')

/**
* Dummy helper that add a string to the templates showing
* if the strings matches. Use to demonstrate the use
* of ZAP helper within the chip-helper environment
*
* @param {*} str1 : First string to compare
* @param {*} str2 : Second string to comapre
*/
function example_helper(str1, str2) {
if (helperZcl.isStrEqual(str1, str2)) {
return 'The two strings are identical'
} else {
return 'The two strings are different'
}
}
// Import helpers from zap core
const zapPath = '../../../third_party/zap/repo/src-electron/';
const cHelper = require(zapPath + 'generator/helper-c.js')
const zclHelper = require(zapPath + 'generator/helper-zcl.js')
const zclQuery = require(zapPath + 'db/query-zcl.js')
const templateUtil = require(zapPath + 'generator/template-util.js')

/**
* Produces the top-of-the-file header for a C file.
*
* @returns The header content
*/
function chip_header() {
function chip_header()
{
return `
/*
*
Expand All @@ -65,10 +54,137 @@ function chip_header() {
*/`;
}

const stringShortTypes = [ 'CHAR_STRING', 'OCTET_STRING' ];
const stringLongTypes = [ 'LONG_CHAR_STRING', 'LONG_OCTET_STRING' ];

function isShortString(type)
{
return stringShortTypes.includes(type);
}

function isLongString(type)
{
return stringLongTypes.includes(type);
}

function isString(type)
{
return isShortString(type) || isLongString(type);
}

function asValueIfNotPresent(type, isArray)
{
if (isString(type) || isArray) {
return 'NULL';
}

function resolve(packageId)
{
const options = { 'hash' : {} };
return cHelper.asUnderlyingZclType.call(this, type, options).then(zclType => {
switch (zclType) {
case 'uint8_t':
return 'UINT8_MAX';
case 'uint16_t':
return 'UINT16_MAX';
case 'uint32_t':
return 'UINT32_MAX';
default:
error = 'Unhandled underlying type ' + zclType + ' for original type ' + type;
throw error;
}
})
}

const promise = templateUtil.ensureZclPackageId(this).then(resolve.bind(this)).catch(err => console.log(err));
return templateUtil.templatePromise(this.global, promise)
}

// TODO Expose the readTypeLength as an additional member field of {{asUnderlyingZclType}} instead
// of having to call this method separately.
function asReadTypeLength(type)
{
if (isShortString(type)) {
return '1u';
}

if (isLongString(type)) {
return '2u';
}

function resolve(packageId)
{
const db = this.global.db;

const defaultResolver = zclQuery.selectAtomicType(db, packageId, type);

const enumResolver = zclHelper.isEnum(db, type, packageId).then(result => {
return result == 'unknown' ? null : zclQuery.selectEnumByName(db, type, packageId).then(rec => {
return zclQuery.selectAtomicType(db, packageId, rec.type);
});
});

const bitmapResolver = zclHelper.isBitmap(db, type, packageId).then(result => {
return result == 'unknown' ? null : zclQuery.selectBitmapByName(db, packageId, type).then(rec => {
return zclQuery.selectAtomicType(db, packageId, rec.type);
});
});

const typeResolver = Promise.all([ defaultResolver, enumResolver, bitmapResolver ]);
return typeResolver.then(types => (types.find(type => type)).size);
}

const promise = templateUtil.ensureZclPackageId(this).then(resolve.bind(this)).catch(err => console.log(err));
return templateUtil.templatePromise(this.global, promise)
}

// TODO Expose the readType as an additional member field of {{asUnderlyingZclType}} instead
// of having to call this method separately.
function asReadType(type)
{
if (isShortString(type)) {
return 'String';
}

if (isLongString(type)) {
return 'LongString';
}

function resolve(packageId)
{
const options = { 'hash' : {} };
return zclHelper.asUnderlyingZclType.call(this, type, options).then(zclType => {
switch (zclType) {
case 'int8_t':
case 'uint8_t':
return 'Int8u';
case 'int16_t':
case 'uint16_t':
return 'Int16u';
case 'int24_t':
case 'uint24_t':
return 'Int24u';
case 'int32_t':
case 'uint32_t':
return 'Int32u';
default:
error = 'Unhandled underlying type ' + zclType + ' for original type ' + type;
throw error;
}
})
}

const promise = templateUtil.ensureZclPackageId(this).then(resolve.bind(this)).catch(err => console.log(err));
return templateUtil.templatePromise(this.global, promise)
}

// WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
//
// Note: these exports are public API. Templates that might have been created in the past and are
// available in the wild might depend on these names.
// If you rename the functions, you need to still maintain old exports list.
exports.chip_header = chip_header;
exports.example_helper = example_helper;
exports.chip_header = chip_header;
exports.isString = isString;
exports.asReadType = asReadType;
exports.asReadTypeLength = asReadTypeLength;
exports.asValueIfNotPresent = asValueIfNotPresent;
30 changes: 30 additions & 0 deletions src/app/zap-templates/override.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
*
* 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.
*/

function atomicType(arg)
{
switch (arg.name) {
case 'attribute_id':
return 'chip::AttributeId';
case 'cluster_id':
return 'chip::ClusterId';
default:
throw 'not overriding';
}
}

exports.atomicType = atomicType
2 changes: 1 addition & 1 deletion third_party/zap/repo
Submodule repo updated 58 files
+12 −0 apack.info
+12 −0 apack.info.dist
+5 −3 docs/custom-zcl.md
+12 −0 docs/sdk-integration.md
+860 −857 docs/zap-schema.svg
+ docs/zap_splash.xcf
+1 −2 package-lock.json
+9 −5 package.json
+4 −1 quasar.conf.js
+43 −15 src-electron/db/db-api.js
+26 −1 src-electron/db/db-mapping.js
+19 −9 src-electron/db/query-config.js
+143 −0 src-electron/db/query-package.js
+120 −50 src-electron/db/query-zcl.js
+3 −1 src-electron/db/zap-schema.sql
+201 −36 src-electron/generator/generation-engine.js
+17 −3 src-electron/generator/helper-c.js
+16 −9 src-electron/generator/helper-endpointconfig.js
+168 −0 src-electron/generator/helper-sdkextension.js
+52 −0 src-electron/generator/helper-session.js
+191 −18 src-electron/generator/helper-zcl.js
+2 −0 src-electron/generator/overridable.js
+1 −0 src-electron/generator/template-engine.js
+104 −0 src-electron/generator/template-util.js
+65 −0 src-electron/main-process/about.js
+47 −37 src-electron/main-process/electron-main.js
+32 −50 src-electron/main-process/menu.js
+23 −18 src-electron/main-process/preference.js
+8 −11 src-electron/main-process/startup.js
+3 −7 src-electron/main-process/ui.js
+4 −6 src-electron/rest/generation.js
+4 −6 src-electron/rest/user-data.js
+71 −33 src-electron/server/ws-server.js
+1 −0 src-electron/util/env.js
+14 −0 src-electron/util/string.js
+11 −1 src-electron/util/types.js
+47 −3 src-electron/util/util.js
+1 −0 src-electron/zcl/zcl-loader-dotdot.js
+10 −3 src-electron/zcl/zcl-loader-silabs.js
+1 −6 src-electron/zcl/zcl-loader.js
+1 −2 src-script/zap-generate.js
+17 −0 src-shared/db-enum.js
+24 −9 src/App.vue
+ src/assets/zap_splash.png
+5 −1 src/boot/ws.js
+25 −0 src/pages/About.vue
+4 −0 src/router/routes.js
+1 −1 test/endpoint-config.test.js
+35 −1 test/gen-template/zigbee/gen-templates.json
+22 −0 test/gen-template/zigbee/sdk-extension.zapt
+6 −11 test/gen-template/zigbee/zap-config.zapt
+42 −2 test/genengine.test.js
+72 −11 test/generation.test.js
+179 −0 test/helpers.test.js
+76 −1 test/query.test.js
+6 −0 test/string.test.js
+25 −2 test/zcl-loader-consecutive.test.js
+8 −0 test/zcl-loader.test.js