source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/LwipMibCompiler/LwipMibCompiler/Program.cs

Last change on this file was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csharp;charset=UTF-8
File size: 14.7 KB
Line 
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
33using System;
34using System.Collections.Generic;
35using System.IO;
36using System.Reflection;
37using System.Text.RegularExpressions;
38using CCodeGeneration;
39using Lextm.SharpSnmpLib.Mib;
40using Lextm.SharpSnmpLib.Mib.Elements.Entities;
41using Lextm.SharpSnmpLib.Mib.Elements.Types;
42using LwipSnmpCodeGeneration;
43
44namespace 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 if (snmpMib.ChildNodes.Count != 0)
130 {
131 // generate code from LWIP object tree
132 Console.WriteLine(" Generating code " + snmpMib.Name);
133 snmpMib.Generate(generatedFile, generatedHeaderFile);
134 }
135 }
136
137 string preservedCode = MibCFile.GetPreservedCode(destFile);
138 if (!string.IsNullOrEmpty(preservedCode))
139 {
140 generatedFile.PreservedCode.Add(new PlainText(preservedCode));
141 }
142 else
143 {
144 generatedFile.PreservedCode.AddRange(generatedFile.Implementation);
145 }
146 generatedFile.Implementation.Clear();
147
148
149 using (StreamWriter fileWriter = new StreamWriter(destHeaderFile))
150 {
151 CGenerator cGenerator = new CGenerator(fileWriter, destHeaderFile, 3, " ", Environment.NewLine);
152 generatedHeaderFile.Save(cGenerator);
153 }
154 using (StreamWriter fileWriter = new StreamWriter(destFile))
155 {
156 CGenerator cGenerator = new CGenerator(fileWriter, destFile, 3, " ", Environment.NewLine);
157 generatedFile.Save(cGenerator);
158 }
159
160 Console.WriteLine(" Done");
161 }
162
163 private static void PrintUsage()
164 {
165 string codeBase = Assembly.GetExecutingAssembly().CodeBase;
166 string appName = Path.GetFileName(codeBase);
167
168 Console.WriteLine("Usage:");
169 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));
170 Console.WriteLine("");
171 Console.WriteLine(" <source MIB file>");
172 Console.WriteLine(" Path and filename of MIB file to convert.");
173 Console.WriteLine("");
174 Console.WriteLine(" <dest C file>");
175 Console.WriteLine(" Destination path and file. If a path is passed only, filename is auto");
176 Console.WriteLine(" generated from MIB file name.");
177 Console.WriteLine("");
178 Console.WriteLine(" <search path X for referred MIB's>");
179 Console.WriteLine(" It's important to provide all referred MIB's in order to correctly ");
180 Console.WriteLine(" resolve all used types.");
181 Console.WriteLine("");
182 }
183
184
185 #region Generation of LWIP Object Tree
186
187 private static void ProcessMibTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode assignedSnmpNode)
188 {
189 foreach (MibTreeNode mtn in mibTreeNode.ChildNodes)
190 {
191 // in theory container nodes may also be scalars or tables at the same time (for now only process real containers)
192 if (mtn.NodeType == MibTreeNodeType.Container)
193 {
194 SnmpTreeNode snmpTreeNode = GenerateSnmpTreeNode(mtn, assignedSnmpNode);
195 assignedSnmpNode.ChildNodes.Add(snmpTreeNode);
196
197 ProcessMibTreeNode(mtn, snmpTreeNode);
198 }
199 else if ((mtn.NodeType & MibTreeNodeType.Scalar) != 0)
200 {
201 SnmpScalarNode snmpScalarNode = GenerateSnmpScalarNode(mtn, assignedSnmpNode);
202 if (snmpScalarNode != null)
203 {
204 assignedSnmpNode.ChildNodes.Add(snmpScalarNode);
205 }
206 }
207 else if ((mtn.NodeType & MibTreeNodeType.Table) != 0)
208 {
209 SnmpTableNode snmpTableNode = GenerateSnmpTableNode(mtn, assignedSnmpNode);
210 if (snmpTableNode != null)
211 {
212 assignedSnmpNode.ChildNodes.Add(snmpTableNode);
213 }
214 }
215 }
216 }
217
218 private static SnmpTreeNode GenerateSnmpTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
219 {
220 SnmpTreeNode result = new SnmpTreeNode(parentNode);
221 result.Name = _alphaNumericRegex.Replace (mibTreeNode.Entity.Name, "");
222 result.Oid = mibTreeNode.Entity.Value;
223 result.FullOid = MibTypesResolver.ResolveOid(mibTreeNode.Entity).GetOidString();
224
225 return result;
226 }
227
228 private static SnmpScalarNode GenerateSnmpScalarNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
229 {
230 ObjectType ote = mibTreeNode.Entity as ObjectType;
231 if (ote != null)
232 {
233 return GenerateSnmpScalarNode(ote, parentNode, ignoreAccessibleFlag);
234 }
235
236 return null;
237 }
238
239 private static SnmpScalarNode GenerateSnmpScalarNode(ObjectType ote, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
240 {
241 SnmpScalarNode result;
242
243 ITypeAssignment mibType = ote.BaseType;
244 IntegerType it = (mibType as IntegerType);
245 if (it != null)
246 {
247 if (ote.ReferredType.Name == Symbol.TruthValue.ToString())
248 {
249 result = new SnmpScalarNodeTruthValue(parentNode);
250 }
251 else if ((it.Type == IntegerType.Types.Integer) || (it.Type == IntegerType.Types.Integer32))
252 {
253 result = new SnmpScalarNodeInt(parentNode);
254 }
255 else
256 {
257 Console.WriteLine(String.Format("Unsupported IntegerType '{0}'!", it.Type));
258 return null;
259 }
260 if (it.IsEnumeration)
261 {
262 result.Restrictions.AddRange(CreateRestrictions(it.Enumeration));
263 }
264 else
265 {
266 result.Restrictions.AddRange(CreateRestrictions(it.Ranges));
267 }
268 }
269 else
270 {
271 UnsignedType ut = (mibType as UnsignedType);
272 if (ut != null)
273 {
274 if ((ut.Type == UnsignedType.Types.Unsigned32) ||
275 (ut.Type == UnsignedType.Types.Gauge32))
276 {
277 result = new SnmpScalarNodeUint(SnmpDataType.Gauge, parentNode);
278 }
279 else if (ut.Type == UnsignedType.Types.Counter32)
280 {
281 result = new SnmpScalarNodeUint(SnmpDataType.Counter, parentNode);
282 }
283 else if (ut.Type == UnsignedType.Types.TimeTicks)
284 {
285 result = new SnmpScalarNodeUint(SnmpDataType.TimeTicks, parentNode);
286 }
287 else if (ut.Type == UnsignedType.Types.Counter64)
288 {
289 result = new SnmpScalarNodeCounter64(parentNode);
290 if ((ut.Ranges != null) && (ut.Ranges.Count > 0))
291 {
292 Console.WriteLine(String.Format("Generation of ranges is not supported for Counter64 type!"));
293 return null;
294 }
295 }
296 else
297 {
298 Console.WriteLine(String.Format("Unsupported UnsignedType '{0}'!", ut.Type));
299 return null;
300 }
301 result.Restrictions.AddRange(CreateRestrictions(ut.Ranges));
302 }
303 else if (mibType is IpAddressType)
304 {
305 result = new SnmpScalarNodeOctetString(SnmpDataType.IpAddress, parentNode);
306 result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
307 }
308 else if (mibType is OpaqueType)
309 {
310 result = new SnmpScalarNodeOctetString(SnmpDataType.Opaque, parentNode);
311 result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
312 }
313 else if (mibType is OctetStringType)
314 {
315 result = new SnmpScalarNodeOctetString(SnmpDataType.OctetString, parentNode);
316 result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
317 }
318 else if (mibType is ObjectIdentifierType)
319 {
320 result = new SnmpScalarNodeObjectIdentifier(parentNode);
321 }
322 else if (mibType is BitsType)
323 {
324 result = new SnmpScalarNodeBits(parentNode, (uint)((mibType as BitsType).Map.GetHighestValue() + 1));
325 result.Restrictions.AddRange(CreateRestrictions(mibType as BitsType));
326 }
327 else
328 {
329 TypeAssignment ta = mibType as TypeAssignment;
330 if (ta != null)
331 {
332 Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}', Type='{2}'!", ta.Module.Name, ta.Name, ta.Type));
333 }
334 else
335 {
336 Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}'!", mibType.Module, mibType.Name));
337 }
338
339 return null;
340 }
341 }
342
343 result.Name = _alphaNumericRegex.Replace(ote.Name, "");
344 result.Oid = ote.Value;
345
346 if (ote.Access == MaxAccess.readWrite)
347 {
348 result.AccessMode = SnmpAccessMode.ReadWrite;
349 }
350 else if (ote.Access == MaxAccess.readOnly)
351 {
352 result.AccessMode = SnmpAccessMode.ReadOnly;
353 }
354 else if (ote.Access == MaxAccess.readCreate)
355 {
356 result.AccessMode = SnmpAccessMode.ReadOnly;
357 }
358 else if (ignoreAccessibleFlag && (ote.Access == MaxAccess.notAccessible))
359 {
360 result.AccessMode = SnmpAccessMode.NotAccessible;
361 }
362 else
363 {
364 // not accessible or unsupported accress type
365 return null;
366 }
367
368 return result;
369 }
370
371 private static IEnumerable<IRestriction> CreateRestrictions(ValueRanges ranges)
372 {
373 List<IRestriction> result = new List<IRestriction>();
374
375 if (ranges != null)
376 {
377 foreach (ValueRange range in ranges)
378 {
379 if (!range.End.HasValue)
380 {
381 result.Add(new IsEqualRestriction(range.Start));
382 }
383 else
384 {
385 result.Add(new IsInRangeRestriction(range.Start, range.End.Value));
386 }
387 }
388 }
389
390 return result;
391 }
392
393 private static IEnumerable<IRestriction> CreateRestrictions(ValueMap map)
394 {
395 if ((map != null) && (map.Count > 0))
396 {
397 return CreateRestrictions(map.GetContinousRanges());
398 }
399
400 return new List<IRestriction>();
401 }
402
403 private static IEnumerable<IRestriction> CreateRestrictions(BitsType bt)
404 {
405 List<IRestriction> result = new List<IRestriction>();
406
407 if ((bt != null) && (bt.Map != null))
408 {
409 result.Add(new BitMaskRestriction(bt.Map.GetBitMask()));
410 }
411
412 return result;
413 }
414
415 private static SnmpTableNode GenerateSnmpTableNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
416 {
417 SnmpTableNode result = new SnmpTableNode(parentNode);
418 result.Name = mibTreeNode.Entity.Name;
419 result.Oid = mibTreeNode.Entity.Value;
420
421 // expect exactly one row entry
422 if ((mibTreeNode.ChildNodes.Count != 1) || ((mibTreeNode.ChildNodes[0].NodeType & MibTreeNodeType.TableRow) == 0) || (mibTreeNode.ChildNodes[0].Entity.Value != 1))
423 {
424 Console.WriteLine("Found table with unsupported properties! Table needs exactly one (fixed) TableRow with OID=1 ! (" + mibTreeNode.Entity.Name + ")");
425 return null;
426 }
427
428 MibTreeNode rowNode = mibTreeNode.ChildNodes[0];
429
430 ObjectType rot = rowNode.Entity as ObjectType;
431 if (rot != null)
432 {
433 if (!String.IsNullOrWhiteSpace(rot.Augments))
434 {
435 result.AugmentedTableRow = rot.Augments;
436
437 // the indeces from another table shall be used because this table is only an extension of it
438 rot = MibTypesResolver.ResolveDeclaration(rot.Module, rot.Augments) as ObjectType;
439 }
440
441 if (rot.Indices != null)
442 {
443 foreach (string index in rot.Indices)
444 {
445 ObjectType indexEntity = MibTypesResolver.ResolveDeclaration(rot.Module, index) as ObjectType;
446 if (indexEntity == null)
447 {
448 Console.WriteLine(String.Format("Could not resolve index '{0}' for table '{1}'! Table omitted!", index, result.Name));
449 return null;
450 }
451
452 result.IndexNodes.Add(GenerateSnmpScalarNode(indexEntity, parentNode, ignoreAccessibleFlag: true));
453 }
454 }
455 }
456
457 if (result.IndexNodes.Count == 0)
458 {
459 // a table cannot be used without index
460 Console.WriteLine("Found table without any index column ! (" + mibTreeNode.Entity.Name + ")");
461 return null;
462 }
463
464 // add child nodes
465 foreach (MibTreeNode cellNode in rowNode.ChildNodes)
466 {
467 SnmpScalarNode ssn = GenerateSnmpScalarNode(cellNode, parentNode);
468 if (ssn != null)
469 {
470 result.CellNodes.Add(ssn);
471 }
472 }
473
474 return result;
475 }
476
477 #endregion
478
479 }
480}
Note: See TracBrowser for help on using the repository browser.