Skip to content

Commit

Permalink
Update the ZAP template to encode/decode commands
Browse files Browse the repository at this point in the history
There are a few issues with the current template.
 1. {{isArray}} is not taken into account. It results into a mismatch between
    the signatures of some clusters methods
 2. Instead of using raw types, such as 'uint8_t', 'uint16_t', the current template
    uses 'enum'. It creates 2 types of issues:
     * The current template generates code that rely on sizeof(type) to move the
       pointer for the payload buffer. It does not work well with 'enum'.
     * The signatures of methods are using raw types. So it ask for a change
       in all the cluster signatures.
  3. The buffer start pointer is mispositioned: It uses 0 instead of cmd->payloadStartIndex
  4. String are using 'uint8_t *', which is OK but the pointer to the payload buffer is not
     moved to take into account the additional bytes with the size of the string
  • Loading branch information
vivien-apple committed Nov 20, 2020
1 parent 188a35f commit 2e644d5
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 9 deletions.
4 changes: 0 additions & 4 deletions src/app/zap-templates/af-structs.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ 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")}}
Expand Down
57 changes: 53 additions & 4 deletions src/app/zap-templates/call-command-handler-src.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,64 @@ 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);
{{#if (isNullable type isArray)}}
uint8_t * {{asSymbol label}};
{{else if (isStrEqual label "groupId")}}
GroupId {{asSymbol label}};
{{else}}
{{asUnderlyingType type}} {{asSymbol label}};
{{/if}}
{{/zcl_command_arguments}}

{{#zcl_command_arguments}}
{{#if presentIf}}
if ({{presentIf}})
{
{{/if}}
{{#if isArray}}
{{asSymbol label}} = (uint8_t *)(cmd->buffer + payloadOffset);
{{else if (isString type)}}
{{asSymbol label}} = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
{{else if (isLongString type)}}
{{asSymbol label}} = emberAfGetLongString(cmd->buffer, payloadOffset, cmd->bufLen);
{{else if (isStrEqual label "groupId")}}
{{asSymbol label}} = (*(GroupId *)(cmd->buffer + payloadOffset));
{{else}}
{{asSymbol label}} = (*({{asUnderlyingType type}} *)(cmd->buffer + payloadOffset));
{{/if}}
{{#unless (isLastElement index count)}}
argOffset+= sizeof({{asUnderlyingType type}});
{{#if (isString type)}}
payloadOffset += emberAfStringLength({{asSymbol label}}) + 1u;
{{else if (isLongString type)}}
payloadOffset += emberAfLongStringLength({{asSymbol label}}) + 2u;
{{else}}
payloadOffset += sizeof({{asUnderlyingType type}});
{{/if}}
{{/unless}}
{{#if presentIf}}
}
else
{
{{#if (isNullable type isArray)}}
{{asSymbol label}} = NULL;
{{else if (isStrEqual type "INT8U")}}
{{asSymbol label}} = UINT8_MAX;
{{else if (isStrEqual type "INT16U")}}
{{asSymbol label}} = UINT16_MAX;
{{else if (isStrEqual type "INT32U")}}
{{asSymbol label}} = UINT32_MAX;
{{else if (isStrEqual type "INT65U")}}
{{asSymbol label}} = UINT64_MAX;
{{else if (isStrEqual type "CLUSTER_ID")}}
{{asSymbol label}} = EMBER_AF_INVALID_CLUSTER_ID
{{/if}}
}
{{/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}});
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}}
Expand Down
2 changes: 1 addition & 1 deletion src/app/zap-templates/callback.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void emberAf{{asCamelCased name false}}Cluster{{asCamelCased side false}}TickCal
*/

{{#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}});
bool emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback({{#zcl_command_arguments}} {{#if isArray}}uint8_t * {{else}}{{asUnderlyingType type}}{{/if}} {{asSymbol label}}{{#unless (isLastElement index count)}}, {{/unless}}{{/zcl_command_arguments}});
{{else}}
bool emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback();
{{/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
15 changes: 15 additions & 0 deletions src/app/zap-templates/helper-chip.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ function isCommandAvailable(clusterSide, incoming, outgoing, source, name) {
return false;
}

function isString(type) {
return type == 'CHAR_STRING' || type == 'OCTET_STRING';
}

function isLongString(type) {
return type == 'LONG_CHAR_STRING' || type == 'LONG_OCTET_STRING';
}

function isNullable(type, isArray) {
return isString(type) || isLongString(type) || isArray;
}

// WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
//
// Note: these exports are public API. Templates that might have been created in the past and are
Expand All @@ -81,3 +93,6 @@ exports.isStrEqual = isStrEqual;
exports.isLastElement = isLastElement;
exports.isEnabled = isEnabled;
exports.isCommandAvailable = isCommandAvailable;
exports.isString = isString;
exports.isLongString = isLongString;
exports.isNullable = isNullable;
49 changes: 49 additions & 0 deletions src/app/zap-templates/override.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
*
* 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';
}
}

function nonAtomicType(arg) {
switch (arg.name) {
case 'Status':
case 'IasEnrollResponseCode':
case 'DoorLockUserStatus':
case 'DoorLockUserType':
case 'StepMode':
case 'HueStepMode':
case 'SaturationStepMode':
case 'MoveMode':
case 'HueMoveMode':
case 'SaturationMoveMode':
case 'HueDirection':
return 'uint8_t';
default:
throw 'not overriding';
}
}

exports.atomicType = atomicType
exports.nonAtomicType = nonAtomicType

0 comments on commit 2e644d5

Please sign in to comment.