summaryrefslogtreecommitdiff
path: root/contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration')
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/IRestriction.cs120
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmp.cs199
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/LwipSnmpCodeGeneration.csproj72
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibCFile.cs196
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/MibHeaderFile.cs129
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/Properties/AssemblyInfo.cs36
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpMib.cs97
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpNode.cs119
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarAggregationNode.cs293
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarArrayNode.cs105
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNode.cs395
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeBits.cs121
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeCounter64.cs72
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeInt.cs86
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeObjectIdentifier.cs90
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeOctetString.cs118
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeTruthValue.cs66
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpScalarNodeUint.cs91
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTableNode.cs332
-rw-r--r--contrib/apps/LwipMibCompiler/LwipSnmpCodeGeneration/SnmpTreeNode.cs242
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);
+ }
+ }
+}