diff options
Diffstat (limited to 'contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration')
20 files changed, 2979 insertions, 0 deletions
diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/IRestriction.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/IRestriction.cs new file mode 100644 index 00000000000..ee2f4536217 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/IRestriction.cs @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; + +namespace LwipSnmpCodeGeneration +{ + public interface IRestriction + { + string GetCheckCodeValid(string varNameToCheck); + string GetCheckCodeInvalid(string varNameToCheck); + } + + public class BitMaskRestriction : IRestriction + { + UInt32 mask; + + public BitMaskRestriction(UInt32 mask) + { + this.mask = mask; + } + + public string GetCheckCodeValid(string varNameToCheck) + { + return String.Format("(({0} & {1}) == {0})", varNameToCheck, this.mask); + } + + public string GetCheckCodeInvalid(string varNameToCheck) + { + return String.Format("(({0} & {1}) != {0})", varNameToCheck, this.mask); + } + } + + public class IsEqualRestriction : IRestriction + { + private Int64 value; + + public IsEqualRestriction(Int64 value) + { + this.value = value; + } + + public long Value + { + get { return value; } + } + + public string GetCheckCodeValid(string varNameToCheck) + { + return String.Format("({0} == {1})", varNameToCheck, this.value); + } + + public string GetCheckCodeInvalid(string varNameToCheck) + { + return String.Format("({0} != {1})", varNameToCheck, this.value); + } + } + + public class IsInRangeRestriction : IRestriction + { + private Int64 rangeStart; + private Int64 rangeEnd; + + public IsInRangeRestriction(Int64 rangeStart, Int64 rangeEnd) + { + this.rangeStart = rangeStart; + this.rangeEnd = rangeEnd; + } + + public long RangeStart + { + get { return this.rangeStart; } + } + + public long RangeEnd + { + get { return this.rangeEnd; } + } + + public string GetCheckCodeValid(string varNameToCheck) + { + return String.Format("(({0} >= {1}) && ({0} <= {2}))", varNameToCheck, this.rangeStart, this.rangeEnd); + } + + public string GetCheckCodeInvalid(string varNameToCheck) + { + return String.Format("(({0} < {1}) || ({0} > {2}))", varNameToCheck, this.rangeStart, this.rangeEnd); + } + } + +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmp.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmp.cs new file mode 100644 index 00000000000..edac59e04ce --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmp.cs @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; + +namespace LwipSnmpCodeGeneration +{ + public static class LwipOpts + { + public static bool GenerateEmptyFolders = false; + /// <summary> + /// If a tree node only has scalar nodes as child nodes, it is replaced by + /// a single scalar array node in order to save memory and have only one single get/test/set method for all scalars. + /// </summary> + public static bool GenerateScalarArrays = true; + /// <summary> + /// If a tree node has multiple scalars as subnodes as well as other treenodes it + /// defines a single get/test/set method for all scalar child node. + /// (without other treenodes as child it would have been converted to scalar array node). + /// </summary> + public static bool GenerateSingleAccessMethodsForTreeNodeScalars = GenerateScalarArrays; + } + + public static class LwipDefs + { + public const string Null = "NULL"; + public const string Vt_U8 = "u8_t"; + public const string Vt_U16 = "u16_t"; + public const string Vt_U32 = "u32_t"; + public const string Vt_S8 = "s8_t"; + public const string Vt_S16 = "s16_t"; + public const string Vt_S32 = "s32_t"; + public const string Vt_Snmp_err = "snmp_err_t"; + + public const string Incl_SnmpOpts = "lwip/apps/snmp_opts.h"; + public const string Opt_SnmpEnabled = "LWIP_SNMP"; + + public const string Vt_StMib = "struct snmp_mib"; + public const string Vt_StObjectId = "struct snmp_obj_id"; + public const string Vt_StNode = "struct snmp_node"; + public const string Vt_StNodeInstance = "struct snmp_node_instance"; + public const string Vt_StTreeNode = "struct snmp_tree_node"; + public const string Vt_StScalarNode = "struct snmp_scalar_node"; + public const string Vt_StScalarArrayNode = "struct snmp_scalar_array_node"; + public const string Vt_StScalarArrayNodeDef = "struct snmp_scalar_array_node_def"; + public const string Vt_StTableNode = "struct snmp_table_node"; + public const string Vt_StTableColumnDef = "struct snmp_table_col_def"; + public const string Vt_StNextOidState = "struct snmp_next_oid_state"; + + public const string Def_NodeAccessReadOnly = "SNMP_NODE_INSTANCE_READ_ONLY"; + public const string Def_NodeAccessReadWrite = "SNMP_NODE_INSTANCE_READ_WRITE"; + public const string Def_NodeAccessWriteOnly = "SNMP_NODE_INSTANCE_WRITE_ONLY"; + public const string Def_NodeAccessNotAccessible = "SNMP_NODE_INSTANCE_NOT_ACCESSIBLE"; + + public const string Def_ErrorCode_Ok = "SNMP_ERR_NOERROR"; + public const string Def_ErrorCode_WrongValue = "SNMP_ERR_WRONGVALUE"; + public const string Def_ErrorCode_NoSuchInstance = "SNMP_ERR_NOSUCHINSTANCE"; + + public const string FnctSuffix_GetValue = "_get_value"; + public const string FnctSuffix_SetTest = "_set_test"; + public const string FnctSuffix_SetValue = "_set_value"; + public const string FnctSuffix_GetInstance = "_get_instance"; + public const string FnctSuffix_GetNextInstance = "_get_next_instance"; + + public const string FnctName_SetTest_Ok = "snmp_set_test_ok"; + + public static string GetLwipDefForSnmpAccessMode(SnmpAccessMode am) + { + switch (am) + { + case SnmpAccessMode.ReadOnly: return Def_NodeAccessReadOnly; + case SnmpAccessMode.ReadWrite: return Def_NodeAccessReadWrite; + case SnmpAccessMode.NotAccessible: return Def_NodeAccessNotAccessible; + case SnmpAccessMode.WriteOnly: return Def_NodeAccessWriteOnly; + default: throw new NotSupportedException("Unknown SnmpAccessMode!"); + } + } + + public static string GetAsn1DefForSnmpDataType(SnmpDataType dt) + { + switch (dt) + { + // primitive + case SnmpDataType.Null: + return "SNMP_ASN1_TYPE_NULL"; + case SnmpDataType.Bits: + case SnmpDataType.OctetString: + return "SNMP_ASN1_TYPE_OCTET_STRING"; + case SnmpDataType.ObjectIdentifier: + return "SNMP_ASN1_TYPE_OBJECT_ID"; + case SnmpDataType.Integer: + return "SNMP_ASN1_TYPE_INTEGER"; + + // application + case SnmpDataType.IpAddress: + return "SNMP_ASN1_TYPE_IPADDR"; + case SnmpDataType.Counter: + return "SNMP_ASN1_TYPE_COUNTER"; + case SnmpDataType.Gauge: + return "SNMP_ASN1_TYPE_GAUGE"; + case SnmpDataType.TimeTicks: + return "SNMP_ASN1_TYPE_TIMETICKS"; + case SnmpDataType.Opaque: + return "SNMP_ASN1_TYPE_OPAQUE"; + case SnmpDataType.Counter64: + return "SNMP_ASN1_TYPE_COUNTER64"; + default: + throw new NotSupportedException("Unknown SnmpDataType!"); + } + } + + public static string GetLengthForSnmpDataType(SnmpDataType dt) + { + switch (dt) + { + case SnmpDataType.Null: + return "0"; + + case SnmpDataType.Integer: + case SnmpDataType.Counter: + case SnmpDataType.IpAddress: + case SnmpDataType.Gauge: + case SnmpDataType.TimeTicks: + return "4"; + + case SnmpDataType.Counter64: + return "8"; + + case SnmpDataType.OctetString: + case SnmpDataType.ObjectIdentifier: + case SnmpDataType.Bits: + case SnmpDataType.Opaque: + return null; + + default: + throw new NotSupportedException("Unknown SnmpDataType!"); + } + } + } + + public enum SnmpDataType + { + Null, + + Integer, // INTEGER, Integer32 + + Counter, // Counter, Counter32 + Gauge, // Gauge, Gauge32, Unsigned32 + TimeTicks, + + Counter64, + + OctetString, + Opaque, + Bits, + + ObjectIdentifier, + + IpAddress, + } + + public enum SnmpAccessMode + { + ReadOnly, + ReadWrite, + WriteOnly, + NotAccessible + } + +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmpCodeGeneration.csproj b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmpCodeGeneration.csproj new file mode 100644 index 00000000000..f4541c0c18d --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmpCodeGeneration.csproj @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{AABCAB90-1540-45D4-A159-14831A54E9A3}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>LwipSnmpCodeGeneration</RootNamespace> + <AssemblyName>LwipSnmpCodeGeneration</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <TargetFrameworkProfile /> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <Compile Include="IRestriction.cs" /> + <Compile Include="SnmpScalarNodeCounter64.cs" /> + <Compile Include="SnmpScalarNodeTruthValue.cs" /> + <Compile Include="SnmpScalarAggregationNode.cs" /> + <Compile Include="SnmpTableNode.cs" /> + <Compile Include="SnmpScalarArrayNode.cs" /> + <Compile Include="MibHeaderFile.cs" /> + <Compile Include="SnmpScalarNodeBits.cs" /> + <Compile Include="SnmpMib.cs" /> + <Compile Include="SnmpScalarNodeInt.cs" /> + <Compile Include="SnmpScalarNodeObjectIdentifier.cs" /> + <Compile Include="SnmpScalarNodeOctetString.cs" /> + <Compile Include="SnmpScalarNodeUint.cs" /> + <Compile Include="SnmpTreeNode.cs" /> + <Compile Include="LwipSnmp.cs" /> + <Compile Include="MibCFile.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="SnmpNode.cs" /> + <Compile Include="SnmpScalarNode.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\CCodeGeneration\CCodeGeneration.csproj"> + <Project>{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}</Project> + <Name>CCodeGeneration</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibCFile.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibCFile.cs new file mode 100644 index 00000000000..c48ec29d068 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibCFile.cs @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System.Collections.Generic; +using CCodeGeneration; +using System; +using System.IO; + +namespace LwipSnmpCodeGeneration +{ + public class MibCFile + { + #region Fields + + private const string PreservedSectionMarker = "LWIP MIB generator - preserved section begin"; + private const string PreservedSectionHeader = + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + + PreservedSectionMarker + "\n" + + "Code below is preserved on regeneration. Remove these comment lines to regenerate code.\n" + + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; + + private readonly List<CodeElement> includes = new List<CodeElement>(); + private readonly List<CodeElement> defines = new List<CodeElement>(); + private readonly List<CodeElement> declarations = new List<CodeElement>(); + private readonly List<CodeElement> implementation = new List<CodeElement>(); + private readonly List<CodeElement> preservedCode = new List<CodeElement>(); + + #endregion + + public MibCFile() + { + } + + #region Accessors + + public List<CodeElement> Includes + { + get { return this.includes; } + } + + public List<CodeElement> Defines + { + get { return this.defines; } + } + + public List<CodeElement> Declarations + { + get { return this.declarations; } + } + + public List<CodeElement> Implementation + { + get { return this.implementation; } + } + + public List<CodeElement> PreservedCode + { + get { return this.preservedCode; } + } + + #endregion + + #region Methods + + public void Save(CGenerator cGenerator) + { + CFile cFile = new CFile(); + + cFile.AddElement(new Comment("Generated by LwipMibCompiler")); + cFile.AddElement(EmptyLine.SingleLine); + + cFile.AddElement(new PP_Include(LwipDefs.Incl_SnmpOpts)); + CodeContainerBase e = cFile.AddElement(new PP_If(LwipDefs.Opt_SnmpEnabled)) as CodeContainerBase; + e.AddElement(EmptyLine.SingleLine); + + // include header file + string file = cGenerator.FileName; + if (!String.IsNullOrWhiteSpace(file)) + { + string ext = System.IO.Path.GetExtension(file); + + string headerFile = !String.IsNullOrEmpty(ext) ? file.Substring(0, file.Length - ext.Length) : file; + headerFile += ".h"; + + e.AddElement(new PP_Include(headerFile)); + } + + // include common snmp files + e.AddElement(new PP_Include("lwip/apps/snmp.h")); + e.AddElement(new PP_Include("lwip/apps/snmp_core.h")); + e.AddElement(new PP_Include("lwip/apps/snmp_scalar.h")); + e.AddElement(new PP_Include("lwip/apps/snmp_table.h")); + + if (this.includes.Count > 0) + { + e.AddElement(EmptyLine.SingleLine); + e.AddElements(this.includes); + } + + if (this.defines.Count > 0) + { + e.AddElement(EmptyLine.SingleLine); + e.AddElements(this.defines); + } + + if (this.declarations.Count > 0) + { + e.AddElement(EmptyLine.TwoLines); + e.AddElements(this.declarations); + } + + if (this.implementation.Count > 0) + { + e.AddElement(EmptyLine.TwoLines); + e.AddElements(this.implementation); + } + + if (this.preservedCode.Count > 0) + { + e.AddElement(EmptyLine.TwoLines); + e.AddElement(new Comment(PreservedSectionHeader)); + e.AddElement(EmptyLine.SingleLine); + e.AddElements(this.preservedCode); + } + + cFile.Save(cGenerator); + } + + public static string GetPreservedCode(string file) + { + if (File.Exists(file)) + { + using (StreamReader fileStream = new StreamReader(file)) + { + while (!fileStream.EndOfStream) + { + string line = fileStream.ReadLine(); + if (line == PreservedSectionMarker) + { + break; + } + } + + if (!fileStream.EndOfStream) + { + // skip the rest of the comment + spacer line + fileStream.ReadLine(); // "Code below is preserved... + fileStream.ReadLine(); // "+++++++++++++++++++++++... + fileStream.ReadLine(); // */ + fileStream.ReadLine(); // + + string preservedCode = fileStream.ReadToEnd(); + + int lastEndif = preservedCode.LastIndexOf("#endif", StringComparison.Ordinal); + preservedCode = preservedCode.Remove(lastEndif); + + return preservedCode; + } + } + } + + return null; + } + + #endregion + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibHeaderFile.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibHeaderFile.cs new file mode 100644 index 00000000000..95f2a06c5a1 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibHeaderFile.cs @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System.Collections.Generic; +using System.Text.RegularExpressions; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class MibHeaderFile + { + + #region Fields + + private readonly List<CodeElement> defines = new List<CodeElement>(); + private readonly List<CodeElement> includes = new List<CodeElement>(); + private readonly List<CodeElement> functionDeclarations = new List<CodeElement>(); + private readonly List<CodeElement> variableDeclarations = new List<CodeElement>(); + + #endregion + + public MibHeaderFile() + { + } + + #region Accessors + + public List<CodeElement> Defines + { + get { return this.defines; } + } + + public List<CodeElement> Includes + { + get { return this.includes; } + } + + public List<CodeElement> FunctionDeclarations + { + get { return this.functionDeclarations; } + } + + public List<CodeElement> VariableDeclarations + { + get { return this.variableDeclarations; } + } + + #endregion + + #region Methods + + public void Save(CGenerator cGenerator) + { + CFile cFile = new CFile(); + + cFile.AddElement(new Comment("Generated by LwipMibCompiler")); + cFile.AddElement(EmptyLine.SingleLine); + + string headerDefine = cGenerator.FileName; + headerDefine = new Regex("[^a-zA-Z0-9]").Replace(headerDefine, "_"); + headerDefine = headerDefine.ToUpperInvariant(); + + CodeContainerBase e = cFile.AddElement(new PP_Ifdef(headerDefine, inverted: true)) as CodeContainerBase; + e.AddElement(new PP_Macro(headerDefine, headerDefine)); + e.AddElement(EmptyLine.SingleLine); + + e.AddElement(new PP_Include(LwipDefs.Incl_SnmpOpts)); + e = e.AddElement(new PP_If(LwipDefs.Opt_SnmpEnabled)) as CodeContainerBase; + e.AddElement(EmptyLine.SingleLine); + + CodeContainerBase cplusplusopen = e.AddElement(new PP_Ifdef("__cplusplus")) as CodeContainerBase; + cplusplusopen.AddElement(new Code("extern \"C\" {")); + e.AddElement(EmptyLine.SingleLine); + + if (this.includes.Count > 0) + { + e.AddElements(this.includes); + e.AddElement(EmptyLine.SingleLine); + } + + if (this.defines.Count > 0) + { + e.AddElements(this.defines); + e.AddElement(EmptyLine.SingleLine); + } + + e.AddElements(this.functionDeclarations, EmptyLine.SingleLine); + e.AddElements(this.variableDeclarations, EmptyLine.SingleLine); + + e.AddElement(EmptyLine.SingleLine); + CodeContainerBase cplusplusclose = e.AddElement(new PP_Ifdef("__cplusplus")) as CodeContainerBase; + cplusplusclose.AddElement(new Code("}")); + + e.AddElement(EmptyLine.SingleLine); + cFile.Save(cGenerator); + } + + #endregion + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/Properties/AssemblyInfo.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..e68b43d5e5e --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("LwipSnmpCodeGeneration")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LwipSnmpCodeGeneration")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("8cfbbb8b-dfbb-4dd5-80c9-e07845dd58c9")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpMib.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpMib.cs new file mode 100644 index 00000000000..477a18b62af --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpMib.cs @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpMib : SnmpTreeNode + { + public uint[] BaseOid { get; set; } + + public SnmpMib() + : base(null) + { + } + + public SnmpMib(uint[] baseOid) + : base(null) + { + this.BaseOid = baseOid; + } + + public override string FullNodeName + { + get { return this.Name.ToLowerInvariant() + "_root"; } + } + + public override void GenerateCode(MibCFile mibFile) + { + base.GenerateCode(mibFile); + + System.Diagnostics.Debug.Assert((this.BaseOid != null) && (this.BaseOid.Length > 0)); + + // create and add BaseOID declarations + StringBuilder boidInitialization = new StringBuilder("{"); + foreach (uint t in this.BaseOid) + { + boidInitialization.Append(t); + boidInitialization.Append(","); + } + boidInitialization.Length -= 1; + boidInitialization.Append("}"); + + VariableDeclaration boidDecl = new VariableDeclaration( + new VariableType(this.Name.ToLowerInvariant() + "_base_oid", LwipDefs.Vt_U32, null, ConstType.Value, String.Empty), + boidInitialization.ToString(), true); + + mibFile.Declarations.Add(boidDecl); + mibFile.Declarations.Add(GetExportDeclaration()); + } + + public override void GenerateHeaderCode(MibHeaderFile mibHeaderFile) + { + mibHeaderFile.Includes.Add(new PP_Include("lwip/apps/snmp_core.h")); + + mibHeaderFile.VariableDeclarations.Add(VariablePrototype.FromVariableDeclaration(GetExportDeclaration())); + } + + VariableDeclaration GetExportDeclaration() + { + return new VariableDeclaration( + new VariableType(this.Name.ToLowerInvariant(), LwipDefs.Vt_StMib, null, ConstType.Value), + String.Format("{{{0}_base_oid, LWIP_ARRAYSIZE({0}_base_oid), &{1}.node}}", this.Name.ToLowerInvariant(), this.FullNodeName)); + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpNode.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpNode.cs new file mode 100644 index 00000000000..fceb4d5215b --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpNode.cs @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Text.RegularExpressions; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public abstract class SnmpNode + { + public static readonly Regex NameValidationRegex = new Regex(@"^\w+$"); + + private string name; + private readonly SnmpTreeNode parentNode; + + protected SnmpNode(SnmpTreeNode parentNode) + { + this.parentNode = parentNode; + } + + public SnmpTreeNode ParentNode + { + get { return this.parentNode; } + } + + public virtual uint Oid { get; set; } + + public abstract string FullNodeName + { + get; + } + + public virtual string Name + { + get { return this.name; } + set + { + if (value != this.name) + { + // check for valid name + if (!NameValidationRegex.IsMatch(value)) + { + throw new ArgumentOutOfRangeException("Name"); + } + + this.name = value; + } + } + } + + public virtual void Generate(MibCFile generatedFile, MibHeaderFile generatedHeaderFile) + { + int declCount = generatedFile.Declarations.Count; + int implCount = generatedFile.Implementation.Count; + + this.GenerateHeaderCode(generatedHeaderFile); + this.GenerateCode(generatedFile); + + if (generatedFile.Declarations.Count != declCount) + { + generatedFile.Declarations.Add(EmptyLine.SingleLine); + } + if (generatedFile.Implementation.Count != implCount) + { + generatedFile.Implementation.Add(EmptyLine.SingleLine); + } + } + + public abstract void GenerateCode(MibCFile mibFile); + + public virtual void GenerateHeaderCode(MibHeaderFile mibHeaderFile) + { + } + + /// <summary> + /// Called after node structure creation is completed and before code is created. + /// Offers the possibility to perform operations depending on properties/subnodes. + /// If the node shall be transformed to another node(-type) than the own instance + /// may be replaced on parent node by the transformed instance. + /// Calling sequence is always from leafs up to root. So a tree node can assume + /// that the analyze method was already called on all child nodes. + /// E.g. a tree node only has scalar sub nodes -> it transforms itself to a scalar array node + /// </summary> + /// <returns>The transformed node or null if nothing shall be changed in parent structure.</returns> + public virtual void Analyze() + { + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarAggregationNode.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarAggregationNode.cs new file mode 100644 index 00000000000..f5c558c56a9 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarAggregationNode.cs @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System.Collections.Generic; +using System.Globalization; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public abstract class SnmpScalarAggregationNode: SnmpNode + { + private bool getMethodRequired = false; + private bool testMethodRequired = false; + private bool setMethodRequired = false; + + protected SnmpScalarAggregationNode(SnmpTreeNode parentNode) + : base(parentNode) + { + } + + protected virtual string GetMethodName + { + get { return this.FullNodeName + LwipDefs.FnctSuffix_GetValue; } + } + + protected bool GetMethodRequired + { + get { return this.getMethodRequired; } + } + + protected virtual string TestMethodName + { + get { return this.FullNodeName + LwipDefs.FnctSuffix_SetTest; } + } + + protected bool TestMethodRequired + { + get { return this.testMethodRequired; } + } + + protected virtual string SetMethodName + { + get { return this.FullNodeName + LwipDefs.FnctSuffix_SetValue; } + } + + protected bool SetMethodRequired + { + get { return this.setMethodRequired; } + } + + protected abstract IEnumerable<SnmpScalarNode> AggregatedScalarNodes + { + get; + } + + public override void Analyze() + { + base.Analyze(); + + this.getMethodRequired = false; + this.testMethodRequired = false; + this.setMethodRequired = false; + + foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes) + { + if ((scalarNode.AccessMode == SnmpAccessMode.ReadOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite)) + { + this.getMethodRequired = true; + } + if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite)) + { + this.testMethodRequired = true; + this.setMethodRequired = true; + } + + if (this.getMethodRequired && this.setMethodRequired) + { + break; + } + } + } + + protected void GenerateAggregatedCode(MibCFile mibFile, VariableType instanceType, string switchSelector, bool generateDeclarations = true, bool generateImplementations = true) + { + if (this.getMethodRequired) + { + FunctionDeclaration getMethodDecl = new FunctionDeclaration(this.GetMethodName, isStatic: true); + getMethodDecl.Parameter.Add(instanceType); + getMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*")); + getMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_S16); + + if (generateDeclarations) + { + mibFile.Declarations.Add(getMethodDecl); + } + if (generateImplementations) + { + Function getMethod = Function.FromDeclaration(getMethodDecl); + GenerateGetMethodCode(getMethod, switchSelector); + mibFile.Implementation.Add(getMethod); + } + } + + if (this.testMethodRequired) + { + FunctionDeclaration testMethodDecl = new FunctionDeclaration(this.TestMethodName, isStatic: true); + testMethodDecl.Parameter.Add(instanceType); + testMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16)); + testMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*")); + testMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err); + + if (generateDeclarations) + { + mibFile.Declarations.Add(testMethodDecl); + } + if (generateImplementations) + { + Function testMethod = Function.FromDeclaration(testMethodDecl); + GenerateTestMethodCode(testMethod, switchSelector); + mibFile.Implementation.Add(testMethod); + } + } + + if (this.setMethodRequired) + { + FunctionDeclaration setMethodDecl = new FunctionDeclaration(this.SetMethodName, isStatic: true); + setMethodDecl.Parameter.Add(instanceType); + setMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16)); + setMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*")); + setMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err); + + if (generateDeclarations) + { + mibFile.Declarations.Add(setMethodDecl); + } + if (generateImplementations) + { + Function setMethod = Function.FromDeclaration(setMethodDecl); + GenerateSetMethodCode(setMethod, switchSelector); + mibFile.Implementation.Add(setMethod); + } + } + } + + protected virtual void GenerateGetMethodCode(Function getMethod, string switchSelector) + { + VariableDeclaration returnValue = new VariableDeclaration((VariableType)getMethod.ReturnType.Clone()); + returnValue.Type.Name = "value_len"; + getMethod.Declarations.Add(returnValue); + Switch sw = new Switch(switchSelector); + + bool valueVarUsed = false; + + foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes) + { + if ((scalarNode.AccessMode == SnmpAccessMode.ReadOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite)) + { + SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture)); + sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true)); + + scalarNode.GenerateGetMethodCode(sc, getMethod.Parameter[1].Name, ref valueVarUsed, returnValue.Type.Name); + + sw.Switches.Add(sc); + } + } + + SwitchCase scd = SwitchCase.GenerateDefault(); + scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", getMethod.Name, switchSelector); + scd.AddCodeFormat("{0} = 0;", returnValue.Type.Name); + sw.Switches.Add(scd); + + if (!valueVarUsed) + { + getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[1].Name); + } + + getMethod.AddElement(sw); + + getMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + } + + protected virtual void GenerateTestMethodCode(Function testMethod, string switchSelector) + { + VariableDeclaration returnValue = new VariableDeclaration((VariableType)testMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_WrongValue); + returnValue.Type.Name = "err"; + testMethod.Declarations.Add(returnValue); + Switch sw = new Switch(switchSelector); + + bool valueVarUsed = false; + bool lenVarUsed = false; + + foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes) + { + if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite)) + { + SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture)); + sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true)); + + scalarNode.GenerateTestMethodCode(sc, testMethod.Parameter[2].Name, ref valueVarUsed, testMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name); + + sw.Switches.Add(sc); + } + } + + SwitchCase scd = SwitchCase.GenerateDefault(); + scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", testMethod.Name, switchSelector); + sw.Switches.Add(scd); + + if (!valueVarUsed) + { + testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[2].Name); + } + if (!lenVarUsed) + { + testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[1].Name); + } + + testMethod.AddElement(sw); + + testMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + } + + protected virtual void GenerateSetMethodCode(Function setMethod, string switchSelector) + { + VariableDeclaration returnValue = new VariableDeclaration((VariableType)setMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_Ok); + returnValue.Type.Name = "err"; + setMethod.Declarations.Add(returnValue); + Switch sw = new Switch(switchSelector); + + bool valueVarUsed = false; + bool lenVarUsed = false; + + foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes) + { + if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite)) + { + SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture)); + sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true)); + + scalarNode.GenerateSetMethodCode(sc, setMethod.Parameter[2].Name, ref valueVarUsed, setMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name); + + sw.Switches.Add(sc); + } + } + + SwitchCase scd = SwitchCase.GenerateDefault(); + scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", setMethod.Name, switchSelector); + sw.Switches.Add(scd); + + if (!valueVarUsed) + { + setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[2].Name); + } + if (!lenVarUsed) + { + setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[1].Name); + } + + setMethod.AddElement(sw); + + setMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarArrayNode.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarArrayNode.cs new file mode 100644 index 00000000000..086fbb9f6aa --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarArrayNode.cs @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Collections.Generic; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarArrayNode : SnmpScalarAggregationNode + { + private readonly List<SnmpScalarNode> scalarNodes; + + public SnmpScalarArrayNode(List<SnmpScalarNode> scalarNodes, SnmpTreeNode parentNode) + : base(parentNode) + { + this.scalarNodes = scalarNodes; + } + + public override string FullNodeName + { + get { return this.Name.ToLowerInvariant() + "_scalars"; } + } + + protected override IEnumerable<SnmpScalarNode> AggregatedScalarNodes + { + get { return this.scalarNodes; } + } + + public override void GenerateCode(MibCFile mibFile) + { + VariableType instanceType = new VariableType("node", LwipDefs.Vt_StScalarArrayNodeDef, "*", ConstType.Value); + GenerateAggregatedCode( + mibFile, + instanceType, + instanceType.Name + "->oid"); + + + // create and add node definitions + StringBuilder nodeDefs = new StringBuilder(); + foreach (SnmpScalarNode scalarNode in this.scalarNodes) + { + nodeDefs.AppendFormat(" {{{0}, {1}, {2}}}, /* {3} */ \n", + scalarNode.Oid, + LwipDefs.GetAsn1DefForSnmpDataType(scalarNode.DataType), + LwipDefs.GetLwipDefForSnmpAccessMode(scalarNode.AccessMode), + scalarNode.Name); + } + if (nodeDefs.Length > 0) + nodeDefs.Length--; + + VariableDeclaration nodeDefsDecl = new VariableDeclaration( + new VariableType(this.FullNodeName + "_nodes", LwipDefs.Vt_StScalarArrayNodeDef, null, ConstType.Value, String.Empty), + "{\n" + nodeDefs + "\n}" , + isStatic: true); + + mibFile.Declarations.Add(nodeDefsDecl); + + + // create and add node declaration + string nodeInitialization = String.Format("SNMP_SCALAR_CREATE_ARRAY_NODE({0}, {1}, {2}, {3}, {4})", + this.Oid, + nodeDefsDecl.Type.Name, + (this.GetMethodRequired) ? this.GetMethodName : LwipDefs.Null, + (this.TestMethodRequired) ? this.TestMethodName : LwipDefs.Null, + (this.SetMethodRequired) ? this.SetMethodName : LwipDefs.Null + ); + + mibFile.Declarations.Add(new VariableDeclaration( + new VariableType(this.FullNodeName, LwipDefs.Vt_StScalarArrayNode, null, ConstType.Value), + nodeInitialization, + isStatic: true)); + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNode.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNode.cs new file mode 100644 index 00000000000..6be54c49f89 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNode.cs @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Collections.Generic; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNode: SnmpNode + { + protected const string LocalValueName = "v"; // name of (casted) local value variable + + private SnmpDataType dataType; + private SnmpAccessMode accessMode; + private readonly List<IRestriction> restrictions = new List<IRestriction>(); + + private bool useExternalMethods = false; + private string externalGetMethod; + private string externalTestMethod; + private string externalSetMethod; + + + public SnmpScalarNode(SnmpTreeNode parentNode) + : base(parentNode) + { + } + + public override string FullNodeName + { + get { return this.Name.ToLowerInvariant() + "_scalar"; } + } + + public SnmpDataType DataType + { + get { return this.dataType; } + set { this.dataType = value; } + } + + public List<IRestriction> Restrictions + { + get { return this.restrictions; } + } + + public SnmpAccessMode AccessMode + { + get { return this.accessMode; } + set { this.accessMode = value; } + } + + public virtual string FixedValueLength + { + get { return null; } + } + + /// <summary> + /// If scalar is used as a table index its value becomes part of the OID. This value returns how many OID parts are required to represent this value. + /// </summary> + public virtual int OidRepresentationLen + { + get { return -1; } + } + + public bool UseExternalMethods + { + get { return this.useExternalMethods; } + set { this.useExternalMethods = value; } + } + + public string ExternalGetMethod + { + get { return this.externalGetMethod; } + set { this.externalGetMethod = value; } + } + public string ExternalTestMethod + { + get { return this.externalTestMethod; } + set { this.externalTestMethod = value; } + } + public string ExternalSetMethod + { + get { return this.externalSetMethod; } + set { this.externalSetMethod = value; } + } + + public override void GenerateCode(MibCFile mibFile) + { + string getMethodName; + string testMethodName; + string setMethodName; + + if (this.useExternalMethods) + { + getMethodName = this.externalGetMethod; + testMethodName = this.externalTestMethod; + setMethodName = this.externalSetMethod; + } + else + { + getMethodName = LwipDefs.Null; + testMethodName = LwipDefs.Null; + setMethodName = LwipDefs.Null; + + if ((this.accessMode == SnmpAccessMode.ReadWrite) || (this.accessMode == SnmpAccessMode.ReadOnly)) + { + FunctionDeclaration getMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_GetValue, isStatic: true); + getMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*")); + getMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*")); + getMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_S16); + mibFile.Declarations.Add(getMethodDecl); + + Function getMethod = Function.FromDeclaration(getMethodDecl); + getMethodName = getMethod.Name; + + VariableDeclaration returnValue = new VariableDeclaration((VariableType)getMethod.ReturnType.Clone()); + returnValue.Type.Name = "value_len"; + getMethod.Declarations.Add(returnValue); + getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[0].Name); + + bool valueVarUsed = false; + GenerateGetMethodCode(getMethod, getMethod.Parameter[1].Name, ref valueVarUsed, returnValue.Type.Name); + if (!valueVarUsed) + { + getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[1].Name); + } + + getMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + + mibFile.Implementation.Add(getMethod); + } + + if ((this.accessMode == SnmpAccessMode.ReadWrite) || (this.accessMode == SnmpAccessMode.WriteOnly)) + { + bool valueVarUsed; + bool lenVarUsed; + VariableDeclaration returnValue; + + if (this.restrictions.Count > 0) + { + FunctionDeclaration testMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_SetTest, isStatic: true); + testMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*")); + testMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16)); + testMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*")); + testMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err); + mibFile.Declarations.Add(testMethodDecl); + + Function testMethod = Function.FromDeclaration(testMethodDecl); + testMethodName = testMethod.Name; + + returnValue = new VariableDeclaration((VariableType)testMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_WrongValue); + returnValue.Type.Name = "err"; + testMethod.Declarations.Add(returnValue); + testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[0].Name); + + valueVarUsed = false; + lenVarUsed = false; + + GenerateTestMethodCode(testMethod, testMethod.Parameter[2].Name, ref valueVarUsed, testMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name); + + if (!valueVarUsed) + { + testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[2].Name); + } + if (!lenVarUsed) + { + testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[1].Name); + } + + testMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + + mibFile.Implementation.Add(testMethod); + + } + else + { + testMethodName = LwipDefs.FnctName_SetTest_Ok; + } + + FunctionDeclaration setMethodDecl = null; + setMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_SetValue, isStatic: true); + setMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*")); + setMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16)); + setMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*")); + setMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err); + mibFile.Declarations.Add(setMethodDecl); + + Function setMethod = Function.FromDeclaration(setMethodDecl); + setMethodName = setMethod.Name; + + returnValue = new VariableDeclaration((VariableType)setMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_Ok); + returnValue.Type.Name = "err"; + setMethod.Declarations.Add(returnValue); + setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[0].Name); + + valueVarUsed = false; + lenVarUsed = false; + + GenerateSetMethodCode(setMethod, setMethod.Parameter[2].Name, ref valueVarUsed, setMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name); + + if (!valueVarUsed) + { + setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[2].Name); + } + if (!lenVarUsed) + { + setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[1].Name); + } + + setMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + + mibFile.Implementation.Add(setMethod); + } + } + + // create and add node declaration + string nodeInitialization; + if (this.accessMode == SnmpAccessMode.ReadOnly) + { + nodeInitialization = String.Format("SNMP_SCALAR_CREATE_NODE_READONLY({0}, {1}, {2})", + this.Oid, + LwipDefs.GetAsn1DefForSnmpDataType(this.dataType), + getMethodName); + } + else + { + nodeInitialization = String.Format("SNMP_SCALAR_CREATE_NODE({0}, {1}, {2}, {3}, {4}, {5})", + this.Oid, + LwipDefs.GetLwipDefForSnmpAccessMode(this.accessMode), + LwipDefs.GetAsn1DefForSnmpDataType(this.dataType), + getMethodName, + testMethodName, + setMethodName); + } + + mibFile.Declarations.Add(new VariableDeclaration( + new VariableType(this.FullNodeName, LwipDefs.Vt_StScalarNode, null, ConstType.Value), + nodeInitialization, isStatic: true)); + } + + public virtual void GenerateGetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string retLenVarName) + { + bool localValueVarUsed; + if (GenerateValueDeclaration(container, LocalValueName, valueVarName)) + { + valueVarUsed = true; + localValueVarUsed = false; + } + else + { + localValueVarUsed = true; // do not generate UNUSED_ARG code + } + + if (this.FixedValueLength == null) + { + // check that value with variable length fits into buffer + container.AddElement(new Comment(String.Format("TODO: take care that value with variable length fits into buffer: ({0} <= SNMP_MAX_VALUE_SIZE)", retLenVarName), singleLine: true)); + } + + GenerateGetMethodCodeCore(container, LocalValueName, ref localValueVarUsed, retLenVarName); + if (!localValueVarUsed) + { + container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName)); + } + } + + protected virtual void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName) + { + container.AddElement(new Comment(String.Format("TODO: put requested value to '*{0}' here", localValueVarName), singleLine: true)); + container.AddCodeFormat("{0} = {1};", + retLenVarName, + (!String.IsNullOrWhiteSpace(this.FixedValueLength)) ? this.FixedValueLength : "0"); + } + + public virtual void GenerateTestMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + if (this.Restrictions.Count > 0) + { + bool localVarUsed; + if (GenerateValueDeclaration(container, LocalValueName, valueVarName)) + { + valueVarUsed = true; + localVarUsed = false; + } + else + { + localVarUsed = true; // do not generate UNUSED_ARG code + } + + if (!String.IsNullOrWhiteSpace(this.FixedValueLength)) + { + // check for fixed value + container.AddCodeFormat("LWIP_ASSERT(\"Invalid length for datatype\", ({0} == {1}));", lenVarName, this.FixedValueLength); + lenVarUsed = true; + } + + GenerateTestMethodCodeCore(container, LocalValueName, ref localVarUsed, lenVarName, ref lenVarUsed, retErrVarName); + + if (!localVarUsed) + { + container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName)); + } + } + else + { + container.AddCodeFormat("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok); + } + } + + protected virtual void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + container.AddElement(new Comment(String.Format("TODO: test new value here:\nif (*{0} == ) {1} = {2};", localValueVarName, retErrVarName, LwipDefs.Def_ErrorCode_Ok))); + } + + public virtual void GenerateSetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + bool localVarUsed; + if (GenerateValueDeclaration(container, LocalValueName, valueVarName)) + { + valueVarUsed = true; + localVarUsed = false; + } + else + { + localVarUsed = true; // do not generate UNUSED_ARG code + } + + GenerateSetMethodCodeCore(container, LocalValueName, ref localVarUsed, lenVarName, ref lenVarUsed, retErrVarName); + + if (!localVarUsed) + { + container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName)); + } + } + + protected virtual void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + container.AddElement(new Comment(String.Format("TODO: store new value contained in '*{0}' here", localValueVarName), singleLine: true)); + } + + + protected virtual bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName) + { + container.AddDeclaration(new VariableDeclaration( + new VariableType(variableName, LwipDefs.Vt_U8, "*"), + "(" + new VariableType(null, LwipDefs.Vt_U8, "*") + ")" + sourceName)); + + return true; + } + + public static SnmpScalarNode CreateFromDatatype(SnmpDataType dataType, SnmpTreeNode parentNode) + { + switch (dataType) + { + case SnmpDataType.Integer: + return new SnmpScalarNodeInt(parentNode); + + case SnmpDataType.Gauge: + case SnmpDataType.Counter: + case SnmpDataType.TimeTicks: + return new SnmpScalarNodeUint(dataType, parentNode); + } + + return new SnmpScalarNode(parentNode); + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeBits.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeBits.cs new file mode 100644 index 00000000000..906a5a6cf12 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeBits.cs @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNodeBits : SnmpScalarNode + { + private readonly uint bitCount; + + public SnmpScalarNodeBits(SnmpTreeNode parentNode, uint bitCount) + : base(parentNode) + { + this.DataType = SnmpDataType.Bits; + this.bitCount = bitCount; + } + + public override void GenerateGetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string retLenVarName) + { + container.AddCode(String.Format( + "{0} = snmp_encode_bits(({1} *){2}, SNMP_MAX_VALUE_SIZE, 0 /* TODO: pass real value here */, {3});", + retLenVarName, + LwipDefs.Vt_U8, + valueVarName, + this.bitCount)); + + valueVarUsed = true; + } + + public override void GenerateTestMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + if (this.Restrictions.Count > 0) + { + const string bitVarName = "bits"; + + container.Declarations.Add(new VariableDeclaration(new VariableType(bitVarName, LwipDefs.Vt_U32))); + + IfThenElse ite = new IfThenElse(String.Format( + "snmp_decode_bits(({0} *){1}, {2}, &{3}) == ERR_OK", + LwipDefs.Vt_U8, + valueVarName, + lenVarName, + bitVarName)); + + valueVarUsed = true; + lenVarUsed = true; + + StringBuilder innerIfCond = new StringBuilder(); + foreach (IRestriction restriction in this.Restrictions) + { + innerIfCond.Append(restriction.GetCheckCodeValid(bitVarName)); + innerIfCond.Append(" || "); + } + + innerIfCond.Length -= 4; + + IfThenElse innerIte = new IfThenElse(innerIfCond.ToString()); + innerIte.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok)); + ite.AddElement(innerIte); + container.AddElement(ite); + } + else + { + base.GenerateTestMethodCode(container, valueVarName, ref valueVarUsed, lenVarName, ref lenVarUsed, retErrVarName); + } + } + + public override void GenerateSetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + const string bitVarName = "bits"; + + container.Declarations.Add(new VariableDeclaration(new VariableType(bitVarName, LwipDefs.Vt_U32))); + + IfThenElse ite = new IfThenElse(String.Format( + "snmp_decode_bits(({0} *){1}, {2}, &{3}) == ERR_OK", + LwipDefs.Vt_U8, + valueVarName, + lenVarName, + bitVarName)); + + valueVarUsed = true; + lenVarUsed = true; + + ite.AddElement(new Comment(String.Format("TODO: store new value contained in '{0}' here", bitVarName), singleLine: true)); + + container.AddElement(ite); + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeCounter64.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeCounter64.cs new file mode 100644 index 00000000000..8f450c8a510 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeCounter64.cs @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNodeCounter64 : SnmpScalarNode + { + public SnmpScalarNodeCounter64(SnmpTreeNode parentNode) + : base(parentNode) + { + this.DataType = SnmpDataType.Counter64; + } + + protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName) + { + container.AddDeclaration(new VariableDeclaration( + new VariableType(variableName + "_high", LwipDefs.Vt_U32, "*"), + "(" + new VariableType(null, LwipDefs.Vt_U32, "*").ToString() + ")" + sourceName)); + container.AddDeclaration(new VariableDeclaration( + new VariableType(variableName + "_low", LwipDefs.Vt_U32, "*"), + variableName + "_high + 1")); + + container.AddCode(String.Format("LWIP_UNUSED_ARG({0}_high);", variableName)); + container.AddCode(String.Format("LWIP_UNUSED_ARG({0}_low);", variableName)); + + return false; + } + + public override string FixedValueLength + { + get { return String.Format("(2 * sizeof({0}))", LwipDefs.Vt_U32); } + } + + public override int OidRepresentationLen + { + get { return 1; } + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeInt.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeInt.cs new file mode 100644 index 00000000000..a381234cea4 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeInt.cs @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNodeInt : SnmpScalarNode + { + public SnmpScalarNodeInt(SnmpTreeNode parentNode) + : base(parentNode) + { + this.DataType = SnmpDataType.Integer; + } + + protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + System.Diagnostics.Trace.Assert(this.Restrictions.Count > 0); + + StringBuilder ifCond = new StringBuilder(); + foreach (IRestriction restriction in this.Restrictions) + { + ifCond.Append(restriction.GetCheckCodeValid("*" + localValueVarName)); + ifCond.Append(" || "); + + localValueVarUsed = true; + } + + ifCond.Length -= 4; + + IfThenElse ite = new IfThenElse(ifCond.ToString()); + ite.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok)); + container.AddElement(ite); + } + + protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName) + { + container.AddDeclaration(new VariableDeclaration( + new VariableType(variableName, LwipDefs.Vt_S32, "*"), + "(" + new VariableType(null, LwipDefs.Vt_S32, "*") + ")" + sourceName)); + + return true; + } + + public override string FixedValueLength + { + get { return String.Format("sizeof({0})", LwipDefs.Vt_S32); } + } + + public override int OidRepresentationLen + { + get { return 1; } + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeObjectIdentifier.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeObjectIdentifier.cs new file mode 100644 index 00000000000..5ce8d146e04 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeObjectIdentifier.cs @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNodeObjectIdentifier: SnmpScalarNode + { + public SnmpScalarNodeObjectIdentifier(SnmpTreeNode parentNode) + : base(parentNode) + { + this.DataType = SnmpDataType.ObjectIdentifier; + } + + protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName) + { + container.AddDeclaration(new VariableDeclaration( + new VariableType(variableName, LwipDefs.Vt_U32, "*"), + "(" + new VariableType(null, LwipDefs.Vt_U32, "*") + ")" + sourceName)); + + return true; + } + + protected override void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName) + { + container.AddElement(new Comment(String.Format("TODO: put requested value to '*{0}' here. '{0}' has to be interpreted as {1}[]", localValueVarName, LwipDefs.Vt_U32), singleLine: true)); + container.AddElement(EmptyLine.SingleLine); + container.AddCode(String.Format("{0} = 0; // TODO: return real value length here (should be 'numOfElements * sizeof({1})')", retLenVarName, LwipDefs.Vt_U32)); + } + + protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + VariableDeclaration objIdLenVar = new VariableDeclaration( + new VariableType(localValueVarName + "_len", LwipDefs.Vt_U8), + String.Format("{0} / sizeof({1})", lenVarName, LwipDefs.Vt_U32)); + lenVarUsed = true; + + container.Declarations.Add(objIdLenVar); + + base.GenerateTestMethodCodeCore(container, localValueVarName, ref localValueVarUsed, lenVarName, ref lenVarUsed, retErrVarName); + + container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", objIdLenVar.Type.Name)); + } + + protected override void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + VariableDeclaration objIdLenVar = new VariableDeclaration( + new VariableType(localValueVarName + "_len", LwipDefs.Vt_U8), + String.Format("{0} / sizeof({1})", lenVarName, LwipDefs.Vt_U32)); + lenVarUsed = true; + + container.Declarations.Add(objIdLenVar); + + base.GenerateSetMethodCodeCore(container, localValueVarName, ref localValueVarUsed, lenVarName, ref lenVarUsed, retErrVarName); + + container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", objIdLenVar.Type.Name)); + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeOctetString.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeOctetString.cs new file mode 100644 index 00000000000..bf10f9a8d95 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeOctetString.cs @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNodeOctetString : SnmpScalarNode + { + public SnmpScalarNodeOctetString(SnmpDataType dataType, SnmpTreeNode parentNode) + : base(parentNode) + { + System.Diagnostics.Debug.Assert( + (dataType == SnmpDataType.OctetString) || + (dataType == SnmpDataType.Opaque) || + (dataType == SnmpDataType.IpAddress)); + + this.DataType = dataType; + } + + protected override void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName) + { + if (this.Restrictions.Count > 0) + { + StringBuilder ifCond = new StringBuilder(); + foreach (IRestriction restriction in this.Restrictions) + { + ifCond.Append(restriction.GetCheckCodeValid(retLenVarName)); + ifCond.Append(" || "); + } + + ifCond.Length -= 4; + container.AddElement(new Comment("TODO: take care of len restrictions defined in MIB: " + ifCond, singleLine: true)); + } + base.GenerateGetMethodCodeCore(container, localValueVarName, ref localValueVarUsed, retLenVarName); + } + + protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + System.Diagnostics.Trace.Assert(this.Restrictions.Count > 0); + + // checks refer to length of octet string + StringBuilder ifCond = new StringBuilder(); + foreach (IRestriction restriction in this.Restrictions) + { + ifCond.Append(restriction.GetCheckCodeValid(lenVarName)); + ifCond.Append(" || "); + + lenVarUsed = true; + } + + ifCond.Length -= 4; + + IfThenElse ite = new IfThenElse(ifCond.ToString()); + ite.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok)); + container.AddElement(ite); + } + + public override int OidRepresentationLen + { + get + { + // check restrictions if we are set to one fixed length + if ((this.Restrictions != null) && (this.Restrictions.Count > 0)) + { + foreach (IRestriction restriction in this.Restrictions) + { + if (restriction is IsInRangeRestriction) + { + if ((restriction as IsInRangeRestriction).RangeStart == (restriction as IsInRangeRestriction).RangeEnd) + { + return (int)(restriction as IsInRangeRestriction).RangeStart; + } + } + else if (restriction is IsEqualRestriction) + { + return (int)(restriction as IsEqualRestriction).Value; + } + } + } + + return -1; // variable length + } + } + + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeTruthValue.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeTruthValue.cs new file mode 100644 index 00000000000..0f557526903 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeTruthValue.cs @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNodeTruthValue : SnmpScalarNodeInt + { + public SnmpScalarNodeTruthValue(SnmpTreeNode parentNode) + : base(parentNode) + { + } + + protected override void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName) + { + container.AddCodeFormat("snmp_encode_truthvalue({0}, /* TODO: put requested bool value here */ 0);", localValueVarName); + localValueVarUsed = true; + + container.AddCode(String.Format("{0} = {1};", + retLenVarName, + (!String.IsNullOrWhiteSpace(this.FixedValueLength)) ? this.FixedValueLength : "0")); + } + + protected override void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + VariableType truthVar = new VariableType("bool_value", LwipDefs.Vt_U8); + container.Declarations.Add(new VariableDeclaration(truthVar)); + + container.AddCodeFormat("snmp_decode_truthvalue({0}, &{1});", localValueVarName, truthVar.Name); + localValueVarUsed = true; + + container.AddElement(new Comment(String.Format("TODO: store new value contained in '{0}' here", truthVar.Name), singleLine: true)); + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeUint.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeUint.cs new file mode 100644 index 00000000000..edc161ac459 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeUint.cs @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpScalarNodeUint : SnmpScalarNode + { + public SnmpScalarNodeUint(SnmpDataType dataType, SnmpTreeNode parentNode) + : base(parentNode) + { + System.Diagnostics.Debug.Assert( + (dataType == SnmpDataType.Counter) || + (dataType == SnmpDataType.Gauge) || + (dataType == SnmpDataType.TimeTicks)); + + this.DataType = dataType; + } + + protected override void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName) + { + System.Diagnostics.Trace.Assert(this.Restrictions.Count > 0); + + StringBuilder ifCond = new StringBuilder(); + foreach (IRestriction restriction in this.Restrictions) + { + ifCond.Append(restriction.GetCheckCodeValid("*" + localValueVarName)); + ifCond.Append(" || "); + + localValueVarUsed = true; + } + + ifCond.Length -= 4; + + IfThenElse ite = new IfThenElse(ifCond.ToString()); + ite.AddCode(String.Format("{0} = {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok)); + container.AddElement(ite); + } + + protected override bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName) + { + container.AddDeclaration(new VariableDeclaration( + new VariableType(variableName, LwipDefs.Vt_U32, "*"), + "(" + new VariableType(null, LwipDefs.Vt_U32, "*") + ")" + sourceName)); + + return true; + } + + public override string FixedValueLength + { + get { return String.Format("sizeof({0})", LwipDefs.Vt_U32); } + } + + public override int OidRepresentationLen + { + get { return 1; } + } + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTableNode.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTableNode.cs new file mode 100644 index 00000000000..13a3bf27518 --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTableNode.cs @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Collections.Generic; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpTableNode: SnmpScalarAggregationNode + { + private readonly List<SnmpScalarNode> cellNodes = new List<SnmpScalarNode>(); + private readonly List<SnmpScalarNode> indexNodes = new List<SnmpScalarNode>(); + private string augmentedTableRow = null; + + + public SnmpTableNode(SnmpTreeNode parentNode) + : base(parentNode) + { + } + + public List<SnmpScalarNode> CellNodes + { + get { return cellNodes; } + } + + public List<SnmpScalarNode> IndexNodes + { + get { return indexNodes; } + } + + public string AugmentedTableRow + { + get { return this.augmentedTableRow; } + set { this.augmentedTableRow = value; } + } + + public override string FullNodeName + { + get + { + string result = this.Name.ToLowerInvariant(); + if (!result.Contains("table")) + { + result += "_table"; + } + + return result; + } + } + + protected override IEnumerable<SnmpScalarNode> AggregatedScalarNodes + { + get { return this.cellNodes; } + } + + public override void GenerateCode(MibCFile mibFile) + { + FunctionDeclaration getInstanceMethodDecl = new FunctionDeclaration(this.FullNodeName + LwipDefs.FnctSuffix_GetInstance, isStatic: true); + getInstanceMethodDecl.Parameter.Add(new VariableType("column", LwipDefs.Vt_U32, "*", ConstType.Value)); + getInstanceMethodDecl.Parameter.Add(new VariableType("row_oid", LwipDefs.Vt_U32, "*", ConstType.Value)); + getInstanceMethodDecl.Parameter.Add(new VariableType("row_oid_len", LwipDefs.Vt_U8, "")); + getInstanceMethodDecl.Parameter.Add(new VariableType("cell_instance", LwipDefs.Vt_StNodeInstance, "*")); + getInstanceMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err); + mibFile.Declarations.Add(getInstanceMethodDecl); + + Function getInstanceMethod = Function.FromDeclaration(getInstanceMethodDecl); + GenerateGetInstanceMethodCode(getInstanceMethod); + mibFile.Implementation.Add(getInstanceMethod); + + + FunctionDeclaration getNextInstanceMethodDecl = new FunctionDeclaration(this.FullNodeName + LwipDefs.FnctSuffix_GetNextInstance, isStatic: true); + getNextInstanceMethodDecl.Parameter.Add(new VariableType("column", LwipDefs.Vt_U32, "*", ConstType.Value)); + getNextInstanceMethodDecl.Parameter.Add(new VariableType("row_oid", LwipDefs.Vt_StObjectId, "*")); + getNextInstanceMethodDecl.Parameter.Add(new VariableType("cell_instance", LwipDefs.Vt_StNodeInstance, "*")); + getNextInstanceMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err); + mibFile.Declarations.Add(getNextInstanceMethodDecl); + + Function getNextInstanceMethod = Function.FromDeclaration(getNextInstanceMethodDecl); + GenerateGetNextInstanceMethodCode(getNextInstanceMethod); + mibFile.Implementation.Add(getNextInstanceMethod); + + + VariableType instanceType = new VariableType("cell_instance", LwipDefs.Vt_StNodeInstance, "*"); + GenerateAggregatedCode( + mibFile, + instanceType, + String.Format("SNMP_TABLE_GET_COLUMN_FROM_OID({0}->instance_oid.id)", instanceType.Name)); + + + #region create and add column/table definitions + + StringBuilder colDefs = new StringBuilder(); + foreach (SnmpScalarNode colNode in this.cellNodes) + { + colDefs.AppendFormat(" {{{0}, {1}, {2}}}, /* {3} */ \n", + colNode.Oid, + LwipDefs.GetAsn1DefForSnmpDataType(colNode.DataType), + LwipDefs.GetLwipDefForSnmpAccessMode(colNode.AccessMode), + colNode.Name); + } + if (colDefs.Length > 0) + { + colDefs.Length--; + } + + VariableDeclaration colDefsDecl = new VariableDeclaration( + new VariableType(this.FullNodeName + "_columns", LwipDefs.Vt_StTableColumnDef, null, ConstType.Value, String.Empty), + "{\n" + colDefs + "\n}", + isStatic: true); + + mibFile.Declarations.Add(colDefsDecl); + + string nodeInitialization = String.Format("SNMP_TABLE_CREATE({0}, {1}, {2}, {3}, {4}, {5}, {6})", + this.Oid, + colDefsDecl.Type.Name, + getInstanceMethodDecl.Name, getNextInstanceMethodDecl.Name, + (this.GetMethodRequired) ? this.GetMethodName : LwipDefs.Null, + (this.TestMethodRequired) ? this.TestMethodName : LwipDefs.Null, + (this.SetMethodRequired) ? this.SetMethodName : LwipDefs.Null + ); + + mibFile.Declarations.Add(new VariableDeclaration( + new VariableType(this.FullNodeName, LwipDefs.Vt_StTableNode, null, ConstType.Value), + nodeInitialization, + isStatic: true)); + + #endregion + } + + protected virtual void GenerateGetInstanceMethodCode(Function getInstanceMethod) + { + VariableDeclaration returnValue = new VariableDeclaration((VariableType)getInstanceMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_NoSuchInstance); + returnValue.Type.Name = "err"; + getInstanceMethod.Declarations.Add(returnValue); + + int instanceOidLength = 0; + StringBuilder indexColumns = new StringBuilder(); + foreach (SnmpScalarNode indexNode in this.indexNodes) + { + if (instanceOidLength >= 0) + { + if (indexNode.OidRepresentationLen >= 0) + { + instanceOidLength += indexNode.OidRepresentationLen; + } + else + { + // at least one index column has a variable length -> we cannot perform a static check + instanceOidLength = -1; + } + } + + indexColumns.AppendFormat( + " {0} ({1}, OID length = {2})\n", + indexNode.Name, + indexNode.DataType, + (indexNode.OidRepresentationLen >= 0) ? indexNode.OidRepresentationLen.ToString() : "variable"); + } + if (indexColumns.Length > 0) + { + indexColumns.Length--; + + getInstanceMethod.Declarations.Insert(0, new Comment(String.Format( + "The instance OID of this table consists of following (index) column(s):\n{0}", + indexColumns))); + } + + string augmentsHint = ""; + if (!String.IsNullOrWhiteSpace(this.augmentedTableRow)) + { + augmentsHint = String.Format( + "This table augments table '{0}'! Index columns therefore belong to table '{0}'!\n" + + "You may simply call the '*{1}' method of this table.\n\n", + (this.augmentedTableRow.ToLowerInvariant().EndsWith("entry")) ? this.augmentedTableRow.Substring(0, this.augmentedTableRow.Length-5) : this.augmentedTableRow, + LwipDefs.FnctSuffix_GetInstance); + } + + CodeContainerBase ccb = getInstanceMethod; + if (instanceOidLength > 0) + { + IfThenElse ite = new IfThenElse(String.Format("{0} == {1}", getInstanceMethod.Parameter[2].Name, instanceOidLength)); + getInstanceMethod.AddElement(ite); + ccb = ite; + } + + ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[0].Name); + ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[1].Name); + if (instanceOidLength <= 0) + { + ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[2].Name); + } + ccb.AddCodeFormat("LWIP_UNUSED_ARG({0});", getInstanceMethod.Parameter[3].Name); + + ccb.AddElement(new Comment(String.Format( + "TODO: check if '{0}'/'{1}' params contain a valid instance oid for a row\n" + + "If so, set '{2} = {3};'\n\n" + + "snmp_oid_* methods may be used for easier processing of oid\n\n" + + "{4}" + + "In order to avoid decoding OID a second time in subsequent get_value/set_test/set_value methods,\n" + + "you may store an arbitrary value (like a pointer to target value object) in '{5}->reference'/'{5}->reference_len'.\n" + + "But be aware that not always a subsequent method is called -> Do NOT allocate memory here and try to release it in subsequent methods!\n\n" + + "You also may replace function pointers in '{5}' param for get/test/set methods which contain the default values from table definition,\n" + + "in order to provide special methods, for the currently processed cell. Changed pointers are only valid for current request.", + getInstanceMethod.Parameter[1].Name, + getInstanceMethod.Parameter[2].Name, + returnValue.Type.Name, + LwipDefs.Def_ErrorCode_Ok, + augmentsHint, + getInstanceMethod.Parameter[3].Name + ))); + + getInstanceMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + } + + protected virtual void GenerateGetNextInstanceMethodCode(Function getNextInstanceMethod) + { + getNextInstanceMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getNextInstanceMethod.Parameter[0].Name); + getNextInstanceMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getNextInstanceMethod.Parameter[1].Name); + getNextInstanceMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getNextInstanceMethod.Parameter[2].Name); + + VariableDeclaration returnValue = new VariableDeclaration((VariableType)getNextInstanceMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_NoSuchInstance); + returnValue.Type.Name = "err"; + getNextInstanceMethod.Declarations.Add(returnValue); + + StringBuilder indexColumns = new StringBuilder(); + foreach (SnmpScalarNode indexNode in this.indexNodes) + { + indexColumns.AppendFormat( + " {0} ({1}, OID length = {2})\n", + indexNode.Name, + indexNode.DataType, + (indexNode.OidRepresentationLen >= 0) ? indexNode.OidRepresentationLen.ToString() : "variable"); + } + if (indexColumns.Length > 0) + { + indexColumns.Length--; + + getNextInstanceMethod.Declarations.Insert(0, new Comment(String.Format( + "The instance OID of this table consists of following (index) column(s):\n{0}", + indexColumns))); + } + + string augmentsHint = ""; + if (!String.IsNullOrWhiteSpace(this.augmentedTableRow)) + { + augmentsHint = String.Format( + "This table augments table '{0}'! Index columns therefore belong to table '{0}'!\n" + + "You may simply call the '*{1}' method of this table.\n\n", + (this.augmentedTableRow.ToLowerInvariant().EndsWith("entry")) ? this.augmentedTableRow.Substring(0, this.augmentedTableRow.Length-5) : this.augmentedTableRow, + LwipDefs.FnctSuffix_GetNextInstance); + } + + getNextInstanceMethod.AddElement(new Comment(String.Format( + "TODO: analyze '{0}->id'/'{0}->len' and return the subsequent row instance\n" + + "Be aware that '{0}->id'/'{0}->len' must not point to a valid instance or have correct instance length.\n" + + "If '{0}->len' is 0, return the first instance. If '{0}->len' is longer than expected, cut superfluous OID parts.\n" + + "If a valid next instance is found, store it in '{0}->id'/'{0}->len' and set '{1} = {2};'\n\n" + + "snmp_oid_* methods may be used for easier processing of oid\n\n" + + "{3}" + + "In order to avoid decoding OID a second time in subsequent get_value/set_test/set_value methods,\n" + + "you may store an arbitrary value (like a pointer to target value object) in '{4}->reference'/'{4}->reference_len'.\n" + + "But be aware that not always a subsequent method is called -> Do NOT allocate memory here and try to release it in subsequent methods!\n\n" + + "You also may replace function pointers in '{4}' param for get/test/set methods which contain the default values from table definition,\n" + + "in order to provide special methods, for the currently processed cell. Changed pointers are only valid for current request.", + getNextInstanceMethod.Parameter[1].Name, + returnValue.Type.Name, + LwipDefs.Def_ErrorCode_Ok, + augmentsHint, + getNextInstanceMethod.Parameter[2].Name + ))); + + getNextInstanceMethod.AddElement(new Comment(String.Format( + "For easier processing and getting the next instance, you may use the 'snmp_next_oid_*' enumerator.\n" + + "Simply pass all known instance OID's to it and it returns the next valid one:\n\n" + + "{0} state;\n" + + "{1} result_buf;\n" + + "snmp_next_oid_init(&state, {2}->id, {2}->len, result_buf.id, SNMP_MAX_OBJ_ID_LEN);\n" + + "while ({{not all instances passed}}) {{\n" + + " {1} test_oid;\n" + + " {{fill test_oid to create instance oid for next instance}}\n" + + " snmp_next_oid_check(&state, test_oid.id, test_oid.len, {{target_data_ptr}});\n" + + "}}\n" + + "if(state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {{\n" + + " snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);\n" + + " {3}->reference.ptr = state.reference; //==target_data_ptr, for usage in subsequent get/test/set\n" + + " {4} = {5};\n" + + "}}" + , + LwipDefs.Vt_StNextOidState, + LwipDefs.Vt_StObjectId, + getNextInstanceMethod.Parameter[1].Name, + getNextInstanceMethod.Parameter[2].Name, + returnValue.Type.Name, + LwipDefs.Def_ErrorCode_Ok + ))); + + getNextInstanceMethod.AddCodeFormat("return {0};", returnValue.Type.Name); + } + + } +} diff --git a/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTreeNode.cs b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTreeNode.cs new file mode 100644 index 00000000000..bf0c604ee4d --- /dev/null +++ b/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTreeNode.cs @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel <info@cl-soft.de> + * + */ + +using System; +using System.Collections.Generic; +using System.Text; +using CCodeGeneration; + +namespace LwipSnmpCodeGeneration +{ + public class SnmpTreeNode: SnmpScalarAggregationNode + { + private readonly List<SnmpNode> childNodes = new List<SnmpNode>(); + private readonly List<SnmpScalarNode> childScalarNodes = new List<SnmpScalarNode>(); + private string fullOid = ""; + + public SnmpTreeNode(SnmpTreeNode parentNode) + : base(parentNode) + { + } + + public override string FullNodeName + { + get { return this.Name.ToLowerInvariant() + "_treenode"; } + } + + public string FullOid + { + get { return this.fullOid; } + set { this.fullOid = value; } + } + + public List<SnmpNode> ChildNodes + { + get { return this.childNodes; } + } + + protected override IEnumerable<SnmpScalarNode> AggregatedScalarNodes + { + get { return this.childScalarNodes; } + } + + private void GenerateAggregatedCode(MibCFile mibFile, bool generateDeclarations, bool generateImplementations) + { + VariableType instanceType = new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*"); + base.GenerateAggregatedCode( + mibFile, + instanceType, + String.Format("{0}->node->oid", instanceType.Name), + generateDeclarations, + generateImplementations); + } + + private void GenerateAggregateMethodDeclarations(MibCFile mibFile) + { + if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1)) + { + GenerateAggregatedCode(mibFile, true, false); + } + } + + public override void GenerateCode(MibCFile mibFile) + { + string nodeInitialization; + + if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1)) + { + GenerateAggregatedCode(mibFile, false, true); + } + + // create and add node declaration + if (this.childNodes.Count > 0) + { + StringBuilder subnodeArrayInitialization = new StringBuilder(); + + for (int i=0; i<this.childNodes.Count; i++) + { + subnodeArrayInitialization.Append(" &"); + subnodeArrayInitialization.Append(this.childNodes[i].FullNodeName); + subnodeArrayInitialization.Append(".node"); + if (!(this.childNodes[i] is SnmpTreeNode)) + { + subnodeArrayInitialization.Append(".node"); + } + + if (i < (this.childNodes.Count - 1)) + { + subnodeArrayInitialization.Append(",\n"); + } + } + + VariableDeclaration subnodeArray = new VariableDeclaration( + new VariableType(this.Name.ToLowerInvariant() + "_subnodes", LwipDefs.Vt_StNode, "*", ConstType.Both, String.Empty), + "{\n" + subnodeArrayInitialization + "\n}", + isStatic: true); + + mibFile.Declarations.Add(subnodeArray); + + nodeInitialization = String.Format("SNMP_CREATE_TREE_NODE({0}, {1})", this.Oid, subnodeArray.Type.Name); + } + else + { + nodeInitialization = String.Format("SNMP_CREATE_EMPTY_TREE_NODE({0})", this.Oid); + } + + mibFile.Declarations.Add(new VariableDeclaration( + new VariableType(this.FullNodeName, LwipDefs.Vt_StTreeNode, null, ConstType.Value), + nodeInitialization, + isStatic: true)); + } + + public override void Analyze() + { + this.childScalarNodes.Clear(); + + // delegate analyze (don't use enumerator because the child node may change our child collection by e.g. removing or replacing itself) + for (int i=this.ChildNodes.Count-1; i>=0; i--) + { + this.ChildNodes[i].Analyze(); + } + + // collect scalar nodes + foreach (SnmpNode childNode in this.childNodes) + { + SnmpScalarNode scalarNode = childNode as SnmpScalarNode; + if (scalarNode != null) + { + this.childScalarNodes.Add(scalarNode); + } + } + + base.Analyze(); + + // check if we can merge this node to a scalar array node (all childs need to be scalars) + if (this.childNodes.Count > 0) + { + if (LwipOpts.GenerateScalarArrays && (this.childScalarNodes.Count == this.childNodes.Count) && (this.ParentNode != null)) + { + SnmpScalarArrayNode scalarArrayNode = new SnmpScalarArrayNode(this.childScalarNodes, this.ParentNode); + scalarArrayNode.Oid = this.Oid; + scalarArrayNode.Name = this.Name; + scalarArrayNode.Analyze(); + + for (int i=0; i<this.ParentNode.ChildNodes.Count; i++) + { + if (this.ParentNode.ChildNodes[i] == this) + { + this.ParentNode.ChildNodes.RemoveAt(i); + this.ParentNode.ChildNodes.Insert(i, scalarArrayNode); + break; + } + } + } + else if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1)) + { + foreach (SnmpScalarNode scalarNode in this.childScalarNodes) + { + scalarNode.UseExternalMethods = true; + scalarNode.ExternalGetMethod = this.GetMethodName; + scalarNode.ExternalTestMethod = this.TestMethodName; + scalarNode.ExternalSetMethod = this.SetMethodName; + } + } + } + else // if (this.childNodes.Count == 0) + { + if (!LwipOpts.GenerateEmptyFolders && (this.ParentNode != null)) + { + // do not generate this empty folder because it only waste (static) memory + for (int i=0; i<this.ParentNode.ChildNodes.Count; i++) + { + if (this.ParentNode.ChildNodes[i] == this) + { + this.ParentNode.ChildNodes.RemoveAt(i); + break; + } + } + } + } + } + + public override void Generate(MibCFile generatedFile, MibHeaderFile generatedHeaderFile) + { + // generate code of child nodes + foreach (SnmpNode childNode in this.childNodes) + { + if (childNode is SnmpTreeNode) + { + childNode.Generate(generatedFile, generatedHeaderFile); + } + } + + Comment dividerComment = new Comment( + String.Format("--- {0} {1} -----------------------------------------------------", this.Name, this.fullOid), + singleLine: true); + + generatedFile.Declarations.Add(dividerComment); + generatedFile.Implementation.Add(dividerComment); + + this.GenerateAggregateMethodDeclarations(generatedFile); + + foreach (SnmpNode childNode in this.childNodes) + { + if (!(childNode is SnmpTreeNode)) + { + childNode.Generate(generatedFile, generatedHeaderFile); + } + } + + base.Generate(generatedFile, generatedHeaderFile); + } + } +} |