• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25  * OF SUCH DAMAGE.
26  *
27  * This file is part of the lwIP TCP/IP stack.
28  *
29  * Author: Martin Hentschel <info@cl-soft.de>
30  *
31  */
32 
33 using System.Collections.Generic;
34 using System.Globalization;
35 using CCodeGeneration;
36 
37 namespace LwipSnmpCodeGeneration
38 {
39 	public abstract class SnmpScalarAggregationNode: SnmpNode
40 	{
41 		private bool getMethodRequired  = false;
42 		private bool testMethodRequired = false;
43 		private bool setMethodRequired  = false;
44 
SnmpScalarAggregationNode(SnmpTreeNode parentNode)45 		protected SnmpScalarAggregationNode(SnmpTreeNode parentNode)
46 			: base(parentNode)
47 		{
48 		}
49 
50 		protected virtual string GetMethodName
51 		{
52 			get { return this.FullNodeName + LwipDefs.FnctSuffix_GetValue; }
53 		}
54 
55 		protected bool GetMethodRequired
56 		{
57 			get { return this.getMethodRequired; }
58 		}
59 
60 		protected virtual string TestMethodName
61 		{
62 			get { return this.FullNodeName + LwipDefs.FnctSuffix_SetTest; }
63 		}
64 
65 		protected bool TestMethodRequired
66 		{
67 			get { return this.testMethodRequired; }
68 		}
69 
70 		protected virtual string SetMethodName
71 		{
72 			get { return this.FullNodeName + LwipDefs.FnctSuffix_SetValue; }
73 		}
74 
75 		protected bool SetMethodRequired
76 		{
77 			get { return this.setMethodRequired; }
78 		}
79 
80 		protected abstract IEnumerable<SnmpScalarNode> AggregatedScalarNodes
81 		{
82 			get;
83 		}
84 
Analyze()85 		public override void Analyze()
86 		{
87 			base.Analyze();
88 
89 			this.getMethodRequired  = false;
90 			this.testMethodRequired = false;
91 			this.setMethodRequired  = false;
92 
93 			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
94 			{
95 				if ((scalarNode.AccessMode == SnmpAccessMode.ReadOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
96 				{
97 					this.getMethodRequired = true;
98 				}
99 				if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
100 				{
101 					this.testMethodRequired = true;
102 					this.setMethodRequired = true;
103 				}
104 
105 				if (this.getMethodRequired && this.setMethodRequired)
106 				{
107 					break;
108 				}
109 			}
110 		}
111 
GenerateAggregatedCode(MibCFile mibFile, VariableType instanceType, string switchSelector, bool generateDeclarations = true, bool generateImplementations = true)112 		protected void GenerateAggregatedCode(MibCFile mibFile, VariableType instanceType, string switchSelector, bool generateDeclarations = true, bool generateImplementations = true)
113 		{
114 			if (this.getMethodRequired)
115 			{
116 				FunctionDeclaration getMethodDecl = new FunctionDeclaration(this.GetMethodName, isStatic: true);
117 				getMethodDecl.Parameter.Add(instanceType);
118 				getMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
119 				getMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_S16);
120 
121 				if (generateDeclarations)
122 				{
123 					mibFile.Declarations.Add(getMethodDecl);
124 				}
125 				if (generateImplementations)
126 				{
127 					Function getMethod = Function.FromDeclaration(getMethodDecl);
128 					GenerateGetMethodCode(getMethod, switchSelector);
129 					mibFile.Implementation.Add(getMethod);
130 				}
131 			}
132 
133 			if (this.testMethodRequired)
134 			{
135 				FunctionDeclaration testMethodDecl = new FunctionDeclaration(this.TestMethodName, isStatic: true);
136 				testMethodDecl.Parameter.Add(instanceType);
137 				testMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
138 				testMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
139 				testMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
140 
141 				if (generateDeclarations)
142 				{
143 					mibFile.Declarations.Add(testMethodDecl);
144 				}
145 				if (generateImplementations)
146 				{
147 					Function testMethod = Function.FromDeclaration(testMethodDecl);
148 					GenerateTestMethodCode(testMethod, switchSelector);
149 					mibFile.Implementation.Add(testMethod);
150 				}
151 			}
152 
153 			if (this.setMethodRequired)
154 			{
155 				FunctionDeclaration setMethodDecl = new FunctionDeclaration(this.SetMethodName, isStatic: true);
156 				setMethodDecl.Parameter.Add(instanceType);
157 				setMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
158 				setMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
159 				setMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
160 
161 				if (generateDeclarations)
162 				{
163 					mibFile.Declarations.Add(setMethodDecl);
164 				}
165 				if (generateImplementations)
166 				{
167 					Function setMethod = Function.FromDeclaration(setMethodDecl);
168 					GenerateSetMethodCode(setMethod, switchSelector);
169 					mibFile.Implementation.Add(setMethod);
170 				}
171 			}
172 		}
173 
GenerateGetMethodCode(Function getMethod, string switchSelector)174 		protected virtual void GenerateGetMethodCode(Function getMethod, string switchSelector)
175 		{
176 			VariableDeclaration returnValue = new VariableDeclaration((VariableType)getMethod.ReturnType.Clone());
177 			returnValue.Type.Name = "value_len";
178 			getMethod.Declarations.Add(returnValue);
179 			Switch sw = new Switch(switchSelector);
180 
181 			bool valueVarUsed = false;
182 
183 			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
184 			{
185 				if ((scalarNode.AccessMode == SnmpAccessMode.ReadOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
186 				{
187 					SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture));
188 					sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true));
189 
190 					scalarNode.GenerateGetMethodCode(sc, getMethod.Parameter[1].Name, ref valueVarUsed, returnValue.Type.Name);
191 
192 					sw.Switches.Add(sc);
193 				}
194 			}
195 
196 			SwitchCase scd = SwitchCase.GenerateDefault();
197 			scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", getMethod.Name, switchSelector);
198 			scd.AddCodeFormat("{0} = 0;", returnValue.Type.Name);
199 			sw.Switches.Add(scd);
200 
201 			if (!valueVarUsed)
202 			{
203 				getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[1].Name);
204 			}
205 
206 			getMethod.AddElement(sw);
207 
208 			getMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
209 		}
210 
GenerateTestMethodCode(Function testMethod, string switchSelector)211 		protected virtual void GenerateTestMethodCode(Function testMethod, string switchSelector)
212 		{
213 			VariableDeclaration returnValue = new VariableDeclaration((VariableType)testMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_WrongValue);
214 			returnValue.Type.Name = "err";
215 			testMethod.Declarations.Add(returnValue);
216 			Switch sw = new Switch(switchSelector);
217 
218 			bool valueVarUsed = false;
219 			bool lenVarUsed = false;
220 
221 			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
222 			{
223 				if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
224 				{
225 					SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture));
226 					sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true));
227 
228 					scalarNode.GenerateTestMethodCode(sc, testMethod.Parameter[2].Name, ref valueVarUsed, testMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
229 
230 					sw.Switches.Add(sc);
231 				}
232 			}
233 
234 			SwitchCase scd = SwitchCase.GenerateDefault();
235 			scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", testMethod.Name, switchSelector);
236 			sw.Switches.Add(scd);
237 
238 			if (!valueVarUsed)
239 			{
240 				testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[2].Name);
241 			}
242 			if (!lenVarUsed)
243 			{
244 				testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[1].Name);
245 			}
246 
247 			testMethod.AddElement(sw);
248 
249 			testMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
250 		}
251 
GenerateSetMethodCode(Function setMethod, string switchSelector)252 		protected virtual void GenerateSetMethodCode(Function setMethod, string switchSelector)
253 		{
254 			VariableDeclaration returnValue = new VariableDeclaration((VariableType)setMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_Ok);
255 			returnValue.Type.Name = "err";
256 			setMethod.Declarations.Add(returnValue);
257 			Switch sw = new Switch(switchSelector);
258 
259 			bool valueVarUsed = false;
260 			bool lenVarUsed = false;
261 
262 			foreach (SnmpScalarNode scalarNode in this.AggregatedScalarNodes)
263 			{
264 				if ((scalarNode.AccessMode == SnmpAccessMode.WriteOnly) || (scalarNode.AccessMode == SnmpAccessMode.ReadWrite))
265 				{
266 					SwitchCase sc = new SwitchCase(scalarNode.Oid.ToString(CultureInfo.InvariantCulture));
267 					sc.Declarations.Add(new Comment(scalarNode.Name, singleLine: true));
268 
269 					scalarNode.GenerateSetMethodCode(sc, setMethod.Parameter[2].Name, ref valueVarUsed, setMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
270 
271 					sw.Switches.Add(sc);
272 				}
273 			}
274 
275 			SwitchCase scd = SwitchCase.GenerateDefault();
276 			scd.AddCodeFormat("LWIP_DEBUGF(SNMP_MIB_DEBUG,(\"{0}(): unknown id: %\"S32_F\"\\n\", {1}));", setMethod.Name, switchSelector);
277 			sw.Switches.Add(scd);
278 
279 			if (!valueVarUsed)
280 			{
281 				setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[2].Name);
282 			}
283 			if (!lenVarUsed)
284 			{
285 				setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[1].Name);
286 			}
287 
288 			setMethod.AddElement(sw);
289 
290 			setMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
291 		}
292 	}
293 }
294