STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
Program.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 System.IO;
36 using System.Reflection;
37 using System.Text.RegularExpressions;
38 using CCodeGeneration;
39 using Lextm.SharpSnmpLib.Mib;
43 
44 namespace LwipMibCompiler
45 {
46  class Program
47  {
48  private static readonly Regex _alphaNumericRegex = new Regex("[^a-zA-Z0-9]");
49 
50  static void Main(string[] args)
51  {
52  Console.WriteLine("lwIP MIB Compiler");
53  Console.WriteLine("");
54 
55  // check args
56  if ((args.Length < 2) || String.IsNullOrWhiteSpace(args[0]) || String.IsNullOrWhiteSpace(args[1]))
57  {
58  PrintUsage();
59  return;
60  }
61 
62  string mibFile = args[0];
63  if (!File.Exists(mibFile))
64  {
65  Console.WriteLine(String.Format("Unable to find file '{0}'!", mibFile));
66  }
67 
68  string destFile = args[1];
69  string destHeaderFile;
70 
71  if (Directory.Exists(destFile))
72  {
73  // only directory passed -> create dest filename from mib filename
74  string mibFileName = Path.GetFileNameWithoutExtension(mibFile).ToLowerInvariant();
75  destFile = Path.Combine(destFile, mibFileName + ".c");
76  }
77 
78  string destFileExt = Path.GetExtension(destFile);
79  if (!String.IsNullOrEmpty(destFileExt))
80  {
81  destHeaderFile = destFile.Substring(0, destFile.Length - destFileExt.Length);
82  }
83  else
84  {
85  destHeaderFile = destFile;
86  }
87  destHeaderFile += ".h";
88 
89  for (int i=2; i<args.Length; i++)
90  {
91  if (!String.IsNullOrWhiteSpace(args[i]) && Directory.Exists(args[i]))
92  {
93  MibTypesResolver.RegisterResolver(new FileSystemMibResolver(args[i], true));
94  }
95  }
96 
97 
98  // read and resolve MIB
99  Console.WriteLine(" Reading MIB file...");
100 
101  MibDocument md = new MibDocument(mibFile);
102  MibTypesResolver.ResolveTypes(md.Modules[0]);
103  MibTree mt = new MibTree(md.Modules[0] as MibModule);
104 
105  if (mt.Root.Count == 0)
106  {
107  Console.WriteLine("No root element found inside MIB!");
108  return;
109  }
110 
111  MibCFile generatedFile = new MibCFile();
112  MibHeaderFile generatedHeaderFile = new MibHeaderFile();
113 
114  foreach (MibTreeNode mibTreeNode in mt.Root)
115  {
116  // create LWIP object tree from MIB structure
117  Console.WriteLine(" Creating lwIP object tree " + mibTreeNode.Entity.Name);
118 
119  SnmpMib snmpMib = new SnmpMib();
120  snmpMib.Oid = mibTreeNode.Entity.Value;
121  snmpMib.BaseOid = MibTypesResolver.ResolveOid(mibTreeNode.Entity).GetOidValues();
122  snmpMib.Name = mibTreeNode.Entity.Name;
123 
124  ProcessMibTreeNode(mibTreeNode, snmpMib);
125 
126  // let the tree transform itself depending on node structure
127  snmpMib.Analyze();
128 
129  // generate code from LWIP object tree
130  Console.WriteLine(" Generating code " + snmpMib.Name);
131  snmpMib.Generate(generatedFile, generatedHeaderFile);
132  }
133 
134  string preservedCode = MibCFile.GetPreservedCode(destFile);
135  if (!string.IsNullOrEmpty(preservedCode))
136  {
137  generatedFile.PreservedCode.Add(new PlainText(preservedCode));
138  }
139  else
140  {
141  generatedFile.PreservedCode.AddRange(generatedFile.Implementation);
142  }
143  generatedFile.Implementation.Clear();
144 
145 
146  using (StreamWriter fileWriter = new StreamWriter(destHeaderFile))
147  {
148  CGenerator cGenerator = new CGenerator(fileWriter, destHeaderFile, 3, " ", Environment.NewLine);
149  generatedHeaderFile.Save(cGenerator);
150  }
151  using (StreamWriter fileWriter = new StreamWriter(destFile))
152  {
153  CGenerator cGenerator = new CGenerator(fileWriter, destFile, 3, " ", Environment.NewLine);
154  generatedFile.Save(cGenerator);
155  }
156 
157  Console.WriteLine(" Done");
158  }
159 
160  private static void PrintUsage()
161  {
162  string codeBase = Assembly.GetExecutingAssembly().CodeBase;
163  string appName = Path.GetFileName(codeBase);
164 
165  Console.WriteLine("Usage:");
166  Console.WriteLine(String.Format(" {0} <source MIB file> <dest C file> [<search path 1 for referred MIB's> <search path 2 for referred MIB's> ...]", appName));
167  Console.WriteLine("");
168  Console.WriteLine(" <source MIB file>");
169  Console.WriteLine(" Path and filename of MIB file to convert.");
170  Console.WriteLine("");
171  Console.WriteLine(" <dest C file>");
172  Console.WriteLine(" Destination path and file. If a path is passed only, filename is auto");
173  Console.WriteLine(" generated from MIB file name.");
174  Console.WriteLine("");
175  Console.WriteLine(" <search path X for referred MIB's>");
176  Console.WriteLine(" It's important to provide all referred MIB's in order to correctly ");
177  Console.WriteLine(" resolve all used types.");
178  Console.WriteLine("");
179  }
180 
181 
182  #region Generation of LWIP Object Tree
183 
184  private static void ProcessMibTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode assignedSnmpNode)
185  {
186  foreach (MibTreeNode mtn in mibTreeNode.ChildNodes)
187  {
188  // in theory container nodes may also be scalars or tables at the same time (for now only process real containers)
189  if (mtn.NodeType == MibTreeNodeType.Container)
190  {
191  SnmpTreeNode snmpTreeNode = GenerateSnmpTreeNode(mtn, assignedSnmpNode);
192  assignedSnmpNode.ChildNodes.Add(snmpTreeNode);
193 
194  ProcessMibTreeNode(mtn, snmpTreeNode);
195  }
196  else if ((mtn.NodeType & MibTreeNodeType.Scalar) != 0)
197  {
198  SnmpScalarNode snmpScalarNode = GenerateSnmpScalarNode(mtn, assignedSnmpNode);
199  if (snmpScalarNode != null)
200  {
201  assignedSnmpNode.ChildNodes.Add(snmpScalarNode);
202  }
203  }
204  else if ((mtn.NodeType & MibTreeNodeType.Table) != 0)
205  {
206  SnmpTableNode snmpTableNode = GenerateSnmpTableNode(mtn, assignedSnmpNode);
207  if (snmpTableNode != null)
208  {
209  assignedSnmpNode.ChildNodes.Add(snmpTableNode);
210  }
211  }
212  }
213  }
214 
215  private static SnmpTreeNode GenerateSnmpTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
216  {
217  SnmpTreeNode result = new SnmpTreeNode(parentNode);
218  result.Name = _alphaNumericRegex.Replace(mibTreeNode.Entity.Name, "").ToLowerInvariant();
219  result.Oid = mibTreeNode.Entity.Value;
220  result.FullOid = MibTypesResolver.ResolveOid(mibTreeNode.Entity).GetOidString();
221 
222  return result;
223  }
224 
225  private static SnmpScalarNode GenerateSnmpScalarNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
226  {
227  ObjectType ote = mibTreeNode.Entity as ObjectType;
228  if (ote != null)
229  {
230  return GenerateSnmpScalarNode(ote, parentNode, ignoreAccessibleFlag);
231  }
232 
233  return null;
234  }
235 
236  private static SnmpScalarNode GenerateSnmpScalarNode(ObjectType ote, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
237  {
238  SnmpScalarNode result;
239 
240  ITypeAssignment mibType = ote.BaseType;
241  IntegerType it = (mibType as IntegerType);
242  if (it != null)
243  {
245  {
246  result = new SnmpScalarNodeTruthValue(parentNode);
247  }
248  else if ((it.Type == IntegerType.Types.Integer) || (it.Type == IntegerType.Types.Integer32))
249  {
250  result = new SnmpScalarNodeInt(parentNode);
251  }
252  else
253  {
254  Console.WriteLine(String.Format("Unsupported IntegerType '{0}'!", it.Type));
255  return null;
256  }
257  if (it.IsEnumeration)
258  {
259  result.Restrictions.AddRange(CreateRestrictions(it.Enumeration));
260  }
261  else
262  {
263  result.Restrictions.AddRange(CreateRestrictions(it.Ranges));
264  }
265  }
266  else
267  {
268  UnsignedType ut = (mibType as UnsignedType);
269  if (ut != null)
270  {
271  if ((ut.Type == UnsignedType.Types.Unsigned32) ||
272  (ut.Type == UnsignedType.Types.Gauge32))
273  {
274  result = new SnmpScalarNodeUint(SnmpDataType.Gauge, parentNode);
275  }
276  else if (ut.Type == UnsignedType.Types.Counter32)
277  {
278  result = new SnmpScalarNodeUint(SnmpDataType.Counter, parentNode);
279  }
280  else if (ut.Type == UnsignedType.Types.TimeTicks)
281  {
282  result = new SnmpScalarNodeUint(SnmpDataType.TimeTicks, parentNode);
283  }
284  else if (ut.Type == UnsignedType.Types.Counter64)
285  {
286  result = new SnmpScalarNodeCounter64(parentNode);
287  if ((ut.Ranges != null) && (ut.Ranges.Count > 0))
288  {
289  Console.WriteLine(String.Format("Generation of ranges is not supported for Counter64 type!"));
290  return null;
291  }
292  }
293  else
294  {
295  Console.WriteLine(String.Format("Unsupported UnsignedType '{0}'!", ut.Type));
296  return null;
297  }
298  result.Restrictions.AddRange(CreateRestrictions(ut.Ranges));
299  }
300  else if (mibType is IpAddressType)
301  {
302  result = new SnmpScalarNodeOctetString(SnmpDataType.IpAddress, parentNode);
303  result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
304  }
305  else if (mibType is OpaqueType)
306  {
307  result = new SnmpScalarNodeOctetString(SnmpDataType.Opaque, parentNode);
308  result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
309  }
310  else if (mibType is OctetStringType)
311  {
312  result = new SnmpScalarNodeOctetString(SnmpDataType.OctetString, parentNode);
313  result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
314  }
315  else if (mibType is ObjectIdentifierType)
316  {
317  result = new SnmpScalarNodeObjectIdentifier(parentNode);
318  }
319  else if (mibType is BitsType)
320  {
321  result = new SnmpScalarNodeBits(parentNode, (uint)((mibType as BitsType).Map.GetHighestValue() + 1));
322  result.Restrictions.AddRange(CreateRestrictions(mibType as BitsType));
323  }
324  else
325  {
326  TypeAssignment ta = mibType as TypeAssignment;
327  if (ta != null)
328  {
329  Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}', Type='{2}'!", ta.Module.Name, ta.Name, ta.Type));
330  }
331  else
332  {
333  Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}'!", mibType.Module, mibType.Name));
334  }
335 
336  return null;
337  }
338  }
339 
340  result.Name = _alphaNumericRegex.Replace(ote.Name, "").ToLowerInvariant();
341  result.Oid = ote.Value;
342 
343  if (ote.Access == MaxAccess.readWrite)
344  {
345  result.AccessMode = SnmpAccessMode.ReadWrite;
346  }
347  else if (ote.Access == MaxAccess.readOnly)
348  {
349  result.AccessMode = SnmpAccessMode.ReadOnly;
350  }
351  else if (ote.Access == MaxAccess.readCreate)
352  {
353  result.AccessMode = SnmpAccessMode.ReadOnly;
354  }
355  else if (ignoreAccessibleFlag && (ote.Access == MaxAccess.notAccessible))
356  {
357  result.AccessMode = SnmpAccessMode.NotAccessible;
358  }
359  else
360  {
361  // not accessible or unsupported accress type
362  return null;
363  }
364 
365  return result;
366  }
367 
368  private static IEnumerable<IRestriction> CreateRestrictions(ValueRanges ranges)
369  {
370  List<IRestriction> result = new List<IRestriction>();
371 
372  if (ranges != null)
373  {
374  foreach (ValueRange range in ranges)
375  {
376  if (!range.End.HasValue)
377  {
378  result.Add(new IsEqualRestriction(range.Start));
379  }
380  else
381  {
382  result.Add(new IsInRangeRestriction(range.Start, range.End.Value));
383  }
384  }
385  }
386 
387  return result;
388  }
389 
390  private static IEnumerable<IRestriction> CreateRestrictions(ValueMap map)
391  {
392  if ((map != null) && (map.Count > 0))
393  {
394  return CreateRestrictions(map.GetContinousRanges());
395  }
396 
397  return new List<IRestriction>();
398  }
399 
400  private static IEnumerable<IRestriction> CreateRestrictions(BitsType bt)
401  {
402  List<IRestriction> result = new List<IRestriction>();
403 
404  if ((bt != null) && (bt.Map != null))
405  {
406  result.Add(new BitMaskRestriction(bt.Map.GetBitMask()));
407  }
408 
409  return result;
410  }
411 
412  private static SnmpTableNode GenerateSnmpTableNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
413  {
414  SnmpTableNode result = new SnmpTableNode(parentNode);
415  result.Name = mibTreeNode.Entity.Name;
416  result.Oid = mibTreeNode.Entity.Value;
417 
418  // expect exactly one row entry
419  if ((mibTreeNode.ChildNodes.Count != 1) || ((mibTreeNode.ChildNodes[0].NodeType & MibTreeNodeType.TableRow) == 0) || (mibTreeNode.ChildNodes[0].Entity.Value != 1))
420  {
421  Console.WriteLine("Found table with unsupported properties! Table needs exactly one (fixed) TableRow with OID=1 ! (" + mibTreeNode.Entity.Name + ")");
422  return null;
423  }
424 
425  MibTreeNode rowNode = mibTreeNode.ChildNodes[0];
426 
427  ObjectType rot = rowNode.Entity as ObjectType;
428  if (rot != null)
429  {
430  if (!String.IsNullOrWhiteSpace(rot.Augments))
431  {
432  result.AugmentedTableRow = rot.Augments;
433 
434  // the indeces from another table shall be used because this table is only an extension of it
435  rot = MibTypesResolver.ResolveDeclaration(rot.Module, rot.Augments) as ObjectType;
436  }
437 
438  if (rot.Indices != null)
439  {
440  foreach (string index in rot.Indices)
441  {
442  ObjectType indexEntity = MibTypesResolver.ResolveDeclaration(rot.Module, index) as ObjectType;
443  if (indexEntity == null)
444  {
445  Console.WriteLine(String.Format("Could not resolve index '{0}' for table '{1}'! Table omitted!", index, result.Name));
446  return null;
447  }
448 
449  result.IndexNodes.Add(GenerateSnmpScalarNode(indexEntity, parentNode, ignoreAccessibleFlag: true));
450  }
451  }
452  }
453 
454  if (result.IndexNodes.Count == 0)
455  {
456  // a table cannot be used without index
457  Console.WriteLine("Found table without any index column ! (" + mibTreeNode.Entity.Name + ")");
458  return null;
459  }
460 
461  // add child nodes
462  foreach (MibTreeNode cellNode in rowNode.ChildNodes)
463  {
464  SnmpScalarNode ssn = GenerateSnmpScalarNode(cellNode, parentNode);
465  if (ssn != null)
466  {
467  result.CellNodes.Add(ssn);
468  }
469  }
470 
471  return result;
472  }
473 
474  #endregion
475 
476  }
477 }
ValueRanges GetContinousRanges()
Returns the values of the map as continous range. At best as one range.
Definition: ValueMap.cs:16
List< MibTreeNode > ChildNodes
Definition: MibTreeNode.cs:51
IList< IModule > Modules
MibModule containing in this document.
Definition: MibDocument.cs:50
override void Generate(MibCFile generatedFile, MibHeaderFile generatedHeaderFile)
IModule Module
Containing module.
Definition: IElement.cs:30
string Name
Module name.
Definition: IModule.cs:42
IList< MibTreeNode > Root
Definition: MibTree.cs:69
static string GetPreservedCode(string file)
Definition: MibCFile.cs:158
Builds up a tree from a single MIB
Definition: MibTree.cs:9
The INTEGER type represents a list of alternatives, or a range of numbers.. Includes Integer32 as it&#39;...
Definition: IntegerType.cs:25
UInt32 GetBitMask()
Interprets the single values as bit positions and creates a mask of it.
Definition: ValueMap.cs:82
List< SnmpScalarNode > IndexNodes
override void Analyze()
Called after node structure creation is completed and before code is created. Offers the possibility ...
static readonly Symbol TruthValue
Definition: Symbol.cs:239
Description of Symbol.
Definition: Symbol.cs:20
override string ToString()
Returns a String that represents this Symbol.
Definition: Symbol.cs:83