STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
SnmpScalarNode.cs
Go to the documentation of this file.
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;
34 using System.Collections.Generic;
35 using CCodeGeneration;
36 
37 namespace LwipSnmpCodeGeneration
38 {
39  public class SnmpScalarNode: SnmpNode
40  {
41  protected const string LocalValueName = "v"; // name of (casted) local value variable
42 
43  private SnmpDataType dataType;
44  private SnmpAccessMode accessMode;
45  private readonly List<IRestriction> restrictions = new List<IRestriction>();
46 
47  private bool useExternalMethods = false;
48  private string externalGetMethod;
49  private string externalTestMethod;
50  private string externalSetMethod;
51 
52 
53  public SnmpScalarNode(SnmpTreeNode parentNode)
54  : base(parentNode)
55  {
56  }
57 
58  public override string FullNodeName
59  {
60  get { return this.Name + "_scalar"; }
61  }
62 
63  public SnmpDataType DataType
64  {
65  get { return this.dataType; }
66  set { this.dataType = value; }
67  }
68 
69  public List<IRestriction> Restrictions
70  {
71  get { return this.restrictions; }
72  }
73 
75  {
76  get { return this.accessMode; }
77  set { this.accessMode = value; }
78  }
79 
80  public virtual string FixedValueLength
81  {
82  get { return null; }
83  }
84 
88  public virtual int OidRepresentationLen
89  {
90  get { return -1; }
91  }
92 
93  public bool UseExternalMethods
94  {
95  get { return this.useExternalMethods; }
96  set { this.useExternalMethods = value; }
97  }
98 
99  public string ExternalGetMethod
100  {
101  get { return this.externalGetMethod; }
102  set { this.externalGetMethod = value; }
103  }
104  public string ExternalTestMethod
105  {
106  get { return this.externalTestMethod; }
107  set { this.externalTestMethod = value; }
108  }
109  public string ExternalSetMethod
110  {
111  get { return this.externalSetMethod; }
112  set { this.externalSetMethod = value; }
113  }
114 
115  public override void GenerateCode(MibCFile mibFile)
116  {
117  string getMethodName;
118  string testMethodName;
119  string setMethodName;
120 
121  if (this.useExternalMethods)
122  {
123  getMethodName = this.externalGetMethod;
124  testMethodName = this.externalTestMethod;
125  setMethodName = this.externalSetMethod;
126  }
127  else
128  {
129  getMethodName = LwipDefs.Null;
130  testMethodName = LwipDefs.Null;
131  setMethodName = LwipDefs.Null;
132 
133  if ((this.accessMode == SnmpAccessMode.ReadWrite) || (this.accessMode == SnmpAccessMode.ReadOnly))
134  {
135  FunctionDeclaration getMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_GetValue, isStatic: true);
136  getMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*"));
137  getMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
138  getMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_U16);
139  mibFile.Declarations.Add(getMethodDecl);
140 
141  Function getMethod = Function.FromDeclaration(getMethodDecl);
142  getMethodName = getMethod.Name;
143 
144  VariableDeclaration returnValue = new VariableDeclaration((VariableType)getMethod.ReturnType.Clone());
145  returnValue.Type.Name = "value_len";
146  getMethod.Declarations.Add(returnValue);
147  getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[0].Name);
148 
149  bool valueVarUsed = false;
150  GenerateGetMethodCode(getMethod, getMethod.Parameter[1].Name, ref valueVarUsed, returnValue.Type.Name);
151  if (!valueVarUsed)
152  {
153  getMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", getMethod.Parameter[1].Name);
154  }
155 
156  getMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
157 
158  mibFile.Implementation.Add(getMethod);
159  }
160 
161  if ((this.accessMode == SnmpAccessMode.ReadWrite) || (this.accessMode == SnmpAccessMode.WriteOnly))
162  {
163  bool valueVarUsed;
164  bool lenVarUsed;
165  VariableDeclaration returnValue;
166 
167  if (this.restrictions.Count > 0)
168  {
169  FunctionDeclaration testMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_SetTest, isStatic: true);
170  testMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*"));
171  testMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
172  testMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
173  testMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
174  mibFile.Declarations.Add(testMethodDecl);
175 
176  Function testMethod = Function.FromDeclaration(testMethodDecl);
177  testMethodName = testMethod.Name;
178 
179  returnValue = new VariableDeclaration((VariableType)testMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_WrongValue);
180  returnValue.Type.Name = "err";
181  testMethod.Declarations.Add(returnValue);
182  testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[0].Name);
183 
184  valueVarUsed = false;
185  lenVarUsed = false;
186 
187  GenerateTestMethodCode(testMethod, testMethod.Parameter[2].Name, ref valueVarUsed, testMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
188 
189  if (!valueVarUsed)
190  {
191  testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[2].Name);
192  }
193  if (!lenVarUsed)
194  {
195  testMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", testMethod.Parameter[1].Name);
196  }
197 
198  testMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
199 
200  mibFile.Implementation.Add(testMethod);
201 
202  }
203  else
204  {
205  testMethodName = LwipDefs.FnctName_SetTest_Ok;
206  }
207 
208  FunctionDeclaration setMethodDecl = null;
209  setMethodDecl = new FunctionDeclaration(this.Name + LwipDefs.FnctSuffix_SetValue, isStatic: true);
210  setMethodDecl.Parameter.Add(new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*"));
211  setMethodDecl.Parameter.Add(new VariableType("len", LwipDefs.Vt_U16));
212  setMethodDecl.Parameter.Add(new VariableType("value", VariableType.VoidString, "*"));
213  setMethodDecl.ReturnType = new VariableType(null, LwipDefs.Vt_Snmp_err);
214  mibFile.Declarations.Add(setMethodDecl);
215 
216  Function setMethod = Function.FromDeclaration(setMethodDecl);
217  setMethodName = setMethod.Name;
218 
219  returnValue = new VariableDeclaration((VariableType)setMethod.ReturnType.Clone(), LwipDefs.Def_ErrorCode_Ok);
220  returnValue.Type.Name = "err";
221  setMethod.Declarations.Add(returnValue);
222  setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[0].Name);
223 
224  valueVarUsed = false;
225  lenVarUsed = false;
226 
227  GenerateSetMethodCode(setMethod, setMethod.Parameter[2].Name, ref valueVarUsed, setMethod.Parameter[1].Name, ref lenVarUsed, returnValue.Type.Name);
228 
229  if (!valueVarUsed)
230  {
231  setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[2].Name);
232  }
233  if (!lenVarUsed)
234  {
235  setMethod.AddCodeFormat("LWIP_UNUSED_ARG({0});", setMethod.Parameter[1].Name);
236  }
237 
238  setMethod.AddCodeFormat("return {0};", returnValue.Type.Name);
239 
240  mibFile.Implementation.Add(setMethod);
241  }
242  }
243 
244  // create and add node declaration
245  string nodeInitialization;
246  if (this.accessMode == SnmpAccessMode.ReadOnly)
247  {
248  nodeInitialization = String.Format("SNMP_SCALAR_CREATE_NODE_READONLY({0}, {1}, {2})",
249  this.Oid,
250  LwipDefs.GetAsn1DefForSnmpDataType(this.dataType),
251  getMethodName);
252  }
253  else
254  {
255  nodeInitialization = String.Format("SNMP_SCALAR_CREATE_NODE({0}, {1}, {2}, {3}, {4}, {5})",
256  this.Oid,
257  LwipDefs.GetLwipDefForSnmpAccessMode(this.accessMode),
258  LwipDefs.GetAsn1DefForSnmpDataType(this.dataType),
259  getMethodName,
260  testMethodName,
261  setMethodName);
262  }
263 
264  mibFile.Declarations.Add(new VariableDeclaration(
265  new VariableType(this.FullNodeName, LwipDefs.Vt_StScalarNode, null, ConstType.Value),
266  nodeInitialization, isStatic: true));
267  }
268 
269  public virtual void GenerateGetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string retLenVarName)
270  {
271  bool localValueVarUsed;
272  if (GenerateValueDeclaration(container, LocalValueName, valueVarName))
273  {
274  valueVarUsed = true;
275  localValueVarUsed = false;
276  }
277  else
278  {
279  localValueVarUsed = true; // do not generate UNUSED_ARG code
280  }
281 
282  if (this.FixedValueLength == null)
283  {
284  // check that value with variable length fits into buffer
285  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));
286  }
287 
288  GenerateGetMethodCodeCore(container, LocalValueName, ref localValueVarUsed, retLenVarName);
289  if (!localValueVarUsed)
290  {
291  container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName));
292  }
293  }
294 
295  protected virtual void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName)
296  {
297  container.AddElement(new Comment(String.Format("TODO: put requested value to '*{0}' here", localValueVarName), singleLine: true));
298  container.AddCodeFormat("{0} = {1};",
299  retLenVarName,
300  (!String.IsNullOrWhiteSpace(this.FixedValueLength)) ? this.FixedValueLength : "0");
301  }
302 
303  public virtual void GenerateTestMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
304  {
305  if (this.Restrictions.Count > 0)
306  {
307  bool localVarUsed;
308  if (GenerateValueDeclaration(container, LocalValueName, valueVarName))
309  {
310  valueVarUsed = true;
311  localVarUsed = false;
312  }
313  else
314  {
315  localVarUsed = true; // do not generate UNUSED_ARG code
316  }
317 
318  if (!String.IsNullOrWhiteSpace(this.FixedValueLength))
319  {
320  // check for fixed value
321  container.AddCodeFormat("LWIP_ASSERT(\"Invalid length for datatype\", ({0} == {1}));", lenVarName, this.FixedValueLength);
322  lenVarUsed = true;
323  }
324 
325  GenerateTestMethodCodeCore(container, LocalValueName, ref localVarUsed, lenVarName, ref lenVarUsed, retErrVarName);
326 
327  if (!localVarUsed)
328  {
329  container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName));
330  }
331  }
332  else
333  {
334  container.AddCodeFormat("{0} == {1};", retErrVarName, LwipDefs.Def_ErrorCode_Ok);
335  }
336  }
337 
338  protected virtual void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
339  {
340  container.AddElement(new Comment(String.Format("TODO: test new value here:\nif (*{0} == ) {1} = {2};", localValueVarName, retErrVarName, LwipDefs.Def_ErrorCode_Ok)));
341  }
342 
343  public virtual void GenerateSetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
344  {
345  bool localVarUsed;
346  if (GenerateValueDeclaration(container, LocalValueName, valueVarName))
347  {
348  valueVarUsed = true;
349  localVarUsed = false;
350  }
351  else
352  {
353  localVarUsed = true; // do not generate UNUSED_ARG code
354  }
355 
356  GenerateSetMethodCodeCore(container, LocalValueName, ref localVarUsed, lenVarName, ref lenVarUsed, retErrVarName);
357 
358  if (!localVarUsed)
359  {
360  container.AddCode(String.Format("LWIP_UNUSED_ARG({0});", LocalValueName));
361  }
362  }
363 
364  protected virtual void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
365  {
366  container.AddElement(new Comment(String.Format("TODO: store new value contained in '*{0}' here", localValueVarName), singleLine: true));
367  }
368 
369 
370  protected virtual bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName)
371  {
372  container.AddDeclaration(new VariableDeclaration(
373  new VariableType(variableName, LwipDefs.Vt_U8, "*"),
374  "(" + new VariableType(null, LwipDefs.Vt_U8, "*") + ")" + sourceName));
375 
376  return true;
377  }
378 
379  public static SnmpScalarNode CreateFromDatatype(SnmpDataType dataType, SnmpTreeNode parentNode)
380  {
381  switch (dataType)
382  {
383  case SnmpDataType.Integer:
384  return new SnmpScalarNodeInt(parentNode);
385 
386  case SnmpDataType.Gauge:
387  case SnmpDataType.Counter:
388  case SnmpDataType.TimeTicks:
389  return new SnmpScalarNodeUint(dataType, parentNode);
390  }
391 
392  return new SnmpScalarNode(parentNode);
393  }
394  }
395 }
virtual void GenerateTestMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
Code AddCodeFormat(string codeFormat, params object[] args)
virtual int OidRepresentationLen
If scalar is used as a table index its value becomes part of the OID. This value returns how many OID...
CodeElement AddDeclaration(CodeElement declaration)
static Function FromDeclaration(FunctionDeclaration decl)
Definition: Function.cs:74
virtual void GenerateSetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
VariableType ReturnType
Definition: Function.cs:62
virtual bool GenerateValueDeclaration(CodeContainerBase container, string variableName, string sourceName)
static SnmpScalarNode CreateFromDatatype(SnmpDataType dataType, SnmpTreeNode parentNode)
List< CodeElement > Implementation
Definition: MibCFile.cs:81
override void GenerateCode(MibCFile mibFile)
virtual void GenerateGetMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string retLenVarName)
List< VariableType > Parameter
Definition: Function.cs:57
virtual void GenerateTestMethodCode(CodeContainerBase container, string valueVarName, ref bool valueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)
SnmpScalarNode(SnmpTreeNode parentNode)
CodeElement AddElement(CodeElement element)
List< CodeElement > Declarations
Definition: MibCFile.cs:76
virtual void GenerateGetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string retLenVarName)
virtual void GenerateSetMethodCodeCore(CodeContainerBase container, string localValueVarName, ref bool localValueVarUsed, string lenVarName, ref bool lenVarUsed, string retErrVarName)