71a2c7ef73ec9b5a35e25ab5d963779250998dd3
[platform/upstream/connectedhomeip.git] / examples / chip-tool / templates / helper.js
1 /*
2  *
3  *    Copyright (c) 2021 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 // Import helpers from zap core
19 const zapPath      = '../../../third_party/zap/repo/src-electron/';
20 const queryImpexp  = require(zapPath + 'db/query-impexp.js')
21 const templateUtil = require(zapPath + 'generator/template-util.js')
22 const zclHelper    = require(zapPath + 'generator/helper-zcl.js')
23 const zclQuery     = require(zapPath + 'db/query-zcl.js')
24 const cHelper      = require(zapPath + 'generator/helper-c.js')
25
26 const StringHelper    = require('../../../src/app/zap-templates/common/StringHelper.js');
27 const ChipTypesHelper = require('../../../src/app/zap-templates/common/ChipTypesHelper.js');
28
29 function hasSpecificResponse(commandName)
30 {
31   // Retrieve the clusterName and the clusterSide. If any if not available, an error will be thrown.
32   const clusterName = this.parent.name;
33   const clusterSide = this.parent.side;
34   if (clusterName == undefined || clusterSide == undefined) {
35     const error = 'chip_server_cluster_commands: Could not find relevant parent cluster.';
36     console.log(error);
37     throw error;
38   }
39
40   function filterCommand(cmd)
41   {
42     return cmd.clusterName == clusterName && cmd.name == (commandName + "Response");
43   }
44
45   function fn(pkgId)
46   {
47     const db = this.global.db;
48     return queryImpexp.exportendPointTypeIds(db, this.global.sessionId)
49         .then(endpointTypes => zclQuery.exportClustersAndEndpointDetailsFromEndpointTypes(db, endpointTypes))
50         .then(endpointsAndClusters => zclQuery.exportCommandDetailsFromAllEndpointTypesAndClusters(db, endpointsAndClusters))
51         .then(endpointCommands => endpointCommands.filter(filterCommand).length)
52   }
53
54   const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => console.log(err));
55   return templateUtil.templatePromise(this.global, promise);
56 }
57
58 function asCallbackAttributeType(attributeType)
59 {
60   switch (parseInt(attributeType)) {
61   case 0x00: // nodata / No data
62   case 0x0A: // data24 / 24-bit data
63   case 0x0C: // data40 / 40-bit data
64   case 0x0D: // data48 / 48-bit data
65   case 0x0E: // data56 / 56-bit data
66   case 0x1A: // map24 / 24-bit bitmap
67   case 0x1C: // map40 / 40-bit bitmap
68   case 0x1D: // map48 / 48-bit bitmap
69   case 0x1E: // map56 / 56-bit bitmap
70   case 0x22: // uint24 / Unsigned 24-bit integer
71   case 0x24: // uint40 / Unsigned 40-bit integer
72   case 0x25: // uint48 / Unsigned 48-bit integer
73   case 0x26: // uint56 / Unsigned 56-bit integer
74   case 0x2A: // int24 / Signed 24-bit integer
75   case 0x2C: // int40 / Signed 40-bit integer
76   case 0x2D: // int48 / Signed 48-bit integer
77   case 0x2E: // int56 / Signed 56-bit integer
78   case 0x38: // semi / Semi-precision
79   case 0x39: // single / Single precision
80   case 0x3A: // double / Double precision
81   case 0x41: // octstr / Octet string
82   case 0x42: // string / Character string
83   case 0x43: // octstr16 / Long octet string
84   case 0x44: // string16 / Long character string
85   case 0x48: // array / Array
86   case 0x49: // struct / Structure
87   case 0x50: // set / Set
88   case 0x51: // bag / Bag
89   case 0xE0: // ToD / Time of day
90     return 'Unsupported';
91   case 0x08: // data8 / 8-bit data
92   case 0x18: // map8 / 8-bit bitmap
93   case 0x20: // uint8 / Unsigned  8-bit integer
94   case 0x30: // enum8 / 8-bit enumeration
95     return 'Int8u';
96   case 0x09: // data16 / 16-bit data
97   case 0x19: // map16 / 16-bit bitmap
98   case 0x21: // uint16 / Unsigned 16-bit integer
99   case 0x31: // enum16 / 16-bit enumeration
100   case 0xE8: // clusterId / Cluster ID
101   case 0xE9: // attribId / Attribute ID
102   case 0xEA: // bacOID / BACnet OID
103   case 0xF1: // key128 / 128-bit security key
104   case 0xFF: // unk / Unknown
105     return 'Int16u';
106   case 0x0B: // data32 / 32-bit data
107   case 0x1B: // map32 / 32-bit bitmap
108   case 0x23: // uint32 / Unsigned 32-bit integer
109   case 0xE1: // date / Date
110   case 0xE2: // UTC / UTCTime
111     return 'Int32u';
112   case 0x0F: // data64 / 64-bit data
113   case 0x1F: // map64 / 64-bit bitmap
114   case 0x27: // uint64 / Unsigned 64-bit integer
115   case 0xF0: // EUI64 / IEEE address
116     return 'Int64u';
117   case 0x10: // bool / Boolean
118     return 'Boolean';
119   case 0x28: // int8 / Signed 8-bit integer
120     return 'Int8s';
121   case 0x29: // int16 / Signed 16-bit integer
122     return 'Int16s';
123   case 0x2B: // int32 / Signed 32-bit integer
124     return 'Int32s';
125   case 0x2F: // int64 / Signed 64-bit integer
126     return 'Int64s';
127   default:
128     error = 'Unhandled attribute type ' + attributeType;
129     throw error;
130   }
131 }
132
133 function asDelimitedCommand(name)
134 {
135   return name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
136 }
137
138 function asTypeMinValue(type)
139 {
140   function fn(pkgId)
141   {
142     const options = { 'hash' : {} };
143     this.isArray  = false;
144     return zclHelper.asUnderlyingZclType.call(this, type, options).then(zclType => {
145       const basicType = ChipTypesHelper.asBasicType(zclType);
146       switch (basicType) {
147       case 'int8_t':
148       case 'int16_t':
149       case 'int32_t':
150       case 'int64_t':
151         return 'INT' + parseInt(basicType.slice(3)) + '_MIN';
152       case 'uint8_t':
153       case 'uint16_t':
154       case 'uint32_t':
155       case 'uint64_t':
156         return '0';
157       default:
158         error = 'Unhandled underlying type ' + zclType + ' for original type ' + type;
159         throw error;
160       }
161     })
162   }
163
164   const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => console.log(err));
165   return templateUtil.templatePromise(this.global, promise);
166 }
167
168 function asTypeMaxValue(type)
169 {
170   function fn(pkgId)
171   {
172     const options = { 'hash' : {} };
173     return zclHelper.asUnderlyingZclType.call(this, type, options).then(zclType => {
174       const basicType = ChipTypesHelper.asBasicType(zclType);
175       switch (basicType) {
176       case 'int8_t':
177       case 'int16_t':
178       case 'int32_t':
179       case 'int64_t':
180         return 'INT' + parseInt(basicType.slice(3)) + '_MAX';
181       case 'uint8_t':
182       case 'uint16_t':
183       case 'uint32_t':
184       case 'uint64_t':
185         return 'UINT' + parseInt(basicType.slice(4)) + '_MAX';
186       default:
187         return 'err';
188         error = 'Unhandled underlying type ' + zclType + ' for original type ' + type;
189         throw error;
190       }
191     })
192   }
193
194   const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => console.log(err));
195   return templateUtil.templatePromise(this.global, promise);
196 }
197
198 function isStrEndsWith(str, substr)
199 {
200   return str.endsWith(substr);
201 }
202
203 //
204 // Module exports
205 //
206 exports.hasSpecificResponse     = hasSpecificResponse;
207 exports.asCallbackAttributeType = asCallbackAttributeType;
208 exports.asDelimitedCommand      = asDelimitedCommand;
209 exports.asTypeMinValue          = asTypeMinValue;
210 exports.asTypeMaxValue          = asTypeMaxValue;
211 exports.isStrEndsWith           = isStrEndsWith;