private void Structs(CommandClass cmdClass, Command cmd, Param vgParam) { const string structPrefixVg = "VG"; const string structPostfixVg = "VG"; string structPrefix = cmd == null && vgParam != null ? structPrefixVg : "ZW"; string structPostfix = cmd == null && vgParam != null ? structPostfixVg : "FRAME"; const string structFieldFormat = "{0}{1,-10}{2,-30}{3}"; if (cmd == null || cmd.Name == "CRC_16_ENCAP" || !cmd.Name.EndsWith(Options1.ChEncapsulatedCommandIdentifier)) { // determine if the command has Param.ParamType.VARIANT or Param.ParamType.BITMASK #region Determine count params and groups int structCount = 1; var list = new SortedList<string, Param>(); list.Add("", null); IList<Param> parameters = null; if (cmd != null) { parameters = cmd.Param; } else if (vgParam != null) { parameters = vgParam.Param1; } if (parameters != null) foreach (Param param in parameters) { if (param.SkipField) continue; if (param.Param1 != null && param.Param1.Count > 0 && (param.Size > 1 || param.SizeReference != null)) { structCount = 4; Structs(cmdClass, null, param); } else { if (param.Bits >= 8) { if (!list.ContainsKey(param.Name)) list.Add(param.Name, param); else throw new ApplicationException("Command " + cmd != null ? cmd.Name : vgParam.Name + " already has parameter " + param.Name); } if (param.Type == zwParamType.BITMASK && param.Size != 1 || param.SizeReference != null) { if (structCount == 4) { SystemLogSingleton.Instance.DoAddLogLine( SystemLogSingleton.Category.Warning, SystemLogSingleton.Action.CodeGeneration, Tools.FormatStr("Multiple VARIANT/BITMASK found in command {0}", cmd != null ? cmd.Name : vgParam.Name) ); break; } structCount = 4; } } } #endregion string versionPostfix = ""; if (cmdClass.Version > 1) versionPostfix = "_V" + cmdClass.Version; for (int structIdx = 1; structIdx <= structCount; structIdx++) { string byteStr = ""; if (structCount > 1) { byteStr = "_" + structIdx + "BYTE"; } Sw.WriteLine("/{0}/", DuplicateStr("*", 60)); if (cmd != null) { Sw.WriteLine("{0,-60}", GetTypeStructCaptionCmd(cmdClass, cmd, byteStr, versionPostfix)); } else if (vgParam != null) { Sw.WriteLine("{0,-60}", GetTypeStructCaptionVg(cmdClass, vgParam, byteStr, versionPostfix)); } Sw.WriteLine("/{0}/", DuplicateStr("*", 60)); if (cmd != null) { Sw.WriteLine("typedef struct _{0}_{1}_{2}_", structPrefix, GetTypeStructNameCmd(cmdClass, cmd, byteStr, versionPostfix), structPostfix); } else if (vgParam != null) { Sw.WriteLine("typedef struct _{0}_{1}_{2}_", structPrefix, GetTypeStructNameVg(cmdClass, vgParam, byteStr, versionPostfix), structPostfix); } Sw.WriteLine("{"); string tab1 = MakeTabs(1); if (cmd != null) { Sw.WriteLine(structFieldFormat, tab1, "uint8_t", "cmdClass;", "/* The command class */"); string cmdName = "cmd;"; string cmdComment = "/* The command */"; if (cmd.Bits > 0 && cmd.Bits < 8) { if (cmd.Param != null && cmd.Param.Count > 0) { cmdName = "cmd_" + Tools.MakeLegalMixCaseIdentifier(cmd.Param[0].Param1[0].Text) + ";"; cmdComment = "/* The command + parameter " + cmd.Param[0].Param1[0].Text + " */"; } } Sw.WriteLine(structFieldFormat, tab1, "uint8_t", cmdName, cmdComment); } #region foreach params parameters = cmd != null ? cmd.Param : vgParam.Param1; if (parameters != null) foreach (Param param in parameters) { if (cmd != null && cmd.Name.StartsWith("SECURITY_MESSAGE_ENCAPSULATION") && param.Name == "commandClassIdentifier") continue; if (cmd != null && cmd.Name.StartsWith("SECURITY_MESSAGE_ENCAPSULATION") && param.Name == "commandIdentifier") continue; if (param.SkipField) continue; if (cmd != null && cmd.Bits > 0 && cmd.Bits < 8 && param.Order == 0 && param.Param1 != null && param.Param1.Count > 0) { } else if (param.Param1 != null && param.Param1.Count > 0 && (param.Size > 1 || param.SizeReference != null)) { for (int i = 1; i <= structIdx; i++) { Sw.WriteLine( structFieldFormat, tab1, Tools.FormatStr("{0}_{1}_{2} ", structPrefixVg, GetTypeStructNameCmd(cmdClass, cmd, _lastVgByteStr, versionPostfix), structPostfixVg), Tools.MakeLegalMixCaseIdentifier("variantGroup" + i) + ";", "/*" + param.Comment + "*/"); } } else { string comment = "/*" + param.Comment + "*/"; if (param.Param1 != null && param.Param1.Count > 0 && param.Bits > 1) { comment = "/* masked byte */"; } int byteFieldCount = 0; if (param.Type == zwParamType.BITMASK && param.Size != 1 || param.SizeReference != null) { byteFieldCount = structIdx; } else if (param.Bits % 8 == 0) { if (param.Bits == 8 && param.Size <= 1) { byteFieldCount = 0; Sw.WriteLine(structFieldFormat, tab1, "uint8_t", Tools.MakeLegalMixCaseIdentifier(param.Text) + ";", comment); } else { byteFieldCount = param.Size <= 1 ? param.Bits / 8 : param.Size * (param.Bits / 8); } } //if (byteFieldCount > 0 && param.Size > 1 && // !((param.Type == zwParamType.BITMASK && param.Size != 1) || param.SizeReference != null)) //{ // sw.WriteLine(StructFieldFormat, tab1, "uint8_t", Tools.MakeLegalMixCaseIdentifier(param.Text) + "[" + byteFieldCount.ToString() + "];", comment); //} //else //{ if (cmd != null && cmd.Name.StartsWith("SECURITY_MESSAGE_ENCAPSULATION") && param.Name == "commandByte") { Sw.WriteLine(structFieldFormat, tab1, "uint8_t", "commandClassIdentifier" + ";", "/**/"); Sw.WriteLine(structFieldFormat, tab1, "uint8_t", "commandIdentifier" + ";", "/**/"); } for (int i = 1; i <= byteFieldCount; i++) { if (i == 1 && byteFieldCount > 1) { comment = "/* MSB */"; } else if (i == byteFieldCount && byteFieldCount > 1) { comment = "/* LSB */"; } else { comment = ""; } if (param.Text.StartsWith("Receiver’s Entropy Input")) { } Sw.WriteLine(structFieldFormat, tab1, "uint8_t", Tools.MakeLegalMixCaseIdentifier(param.Text) + i + ";", comment); } //} } } #endregion Sw.Write("}"); if (cmd != null) { Sw.WriteLine(" {0}_{1}_{2};", structPrefix, GetTypeStructNameCmd(cmdClass, cmd, byteStr, versionPostfix), structPostfix); } else { _lastVgByteStr = byteStr; Sw.WriteLine(" {0}_{1}_{2};", structPrefix, GetTypeStructNameVg(cmdClass, vgParam, byteStr, versionPostfix), structPostfix); } Sw.WriteLine(""); } } }