]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/node.py
a7a4186ba1b7321e09c1155c3f7f6826d224e6c3
[CanFestival-3.git] / objdictgen / node.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 #This file is part of CanFestival, a library implementing CanOpen Stack. 
5 #
6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
7 #
8 #See COPYING file for copyrights details.
9 #
10 #This library is free software; you can redistribute it and/or
11 #modify it under the terms of the GNU Lesser General Public
12 #License as published by the Free Software Foundation; either
13 #version 2.1 of the License, or (at your option) any later version.
14 #
15 #This library is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 #Lesser General Public License for more details.
19 #
20 #You should have received a copy of the GNU Lesser General Public
21 #License along with this library; if not, write to the Free Software
22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24 import cPickle
25 from types import *
26 import re
27
28 """
29 Dictionary of translation between access symbol and their signification
30 """
31 AccessType = {"ro" : "Read Only", "wo" : "Write Only", "rw" : "Read/Write"}
32
33 BoolType = {True : "True", False : "False"} 
34 OptionType = {True : "Yes", False : "No"}
35
36 CustomisableTypes = [(0x02, 0), (0x03, 0), (0x04, 0), (0x05, 0), (0x06, 0), (0x07, 0),
37     (0x08, 0), (0x09, 1), (0x0A, 1), (0x0B, 1), (0x10, 0), (0x11, 0), (0x12, 0),
38     (0x13, 0), (0x14, 0), (0x15, 0), (0x16, 0), (0x18, 0), (0x19, 0), (0x1A, 0),
39     (0x1B, 0)]
40
41 DefaultParams = {"comment" : "", "save" : False}
42
43 #-------------------------------------------------------------------------------
44 #                      Dictionary Mapping and Organisation
45 #-------------------------------------------------------------------------------
46
47 """
48 Properties of entry structure in the Object Dictionary
49 """
50 OD_Subindex = 1             # Entry has at least one subindex
51 OD_MultipleSubindexes = 2   # Entry has more than one subindex
52 OD_IdenticalSubindexes = 4  # Subindexes of entry have the same description
53 OD_IdenticalIndexes = 8     # Entry has the same description on multiple indexes
54
55 """
56 Structures of entry in the Object Dictionary, sum of the properties described above
57 for all sorts of entries use in CAN Open specification
58 """
59 nosub = 0 # Entry without subindex (only for type declaration)
60 var = OD_Subindex
61 array = OD_Subindex | OD_MultipleSubindexes
62 rec = OD_Subindex | OD_MultipleSubindexes | OD_IdenticalSubindexes
63 # Entries identical on multiple indexes
64 plurivar = OD_Subindex | OD_IdenticalIndexes
65 pluriarray = OD_Subindex | OD_MultipleSubindexes | OD_IdenticalIndexes # Example : PDO Parameters
66 plurirec = OD_Subindex | OD_MultipleSubindexes | OD_IdenticalSubindexes |OD_IdenticalIndexes   # Example : PDO Mapping
67
68 """
69 MappingDictionary is the structure used for writing a good organised Object
70 Dictionary. It follows the specifications of the CANOpen standard.
71 Change the informations within it if there is a mistake. But don't modify the
72 organisation of this object, it will involve in a malfunction of the application.
73 """
74
75 MappingDictionary = {
76     0x0001 : {"name" : "BOOLEAN", "struct" : nosub, "size" : 1, "default" : False, "values" : []},
77     0x0002 : {"name" : "INTEGER8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
78     0x0003 : {"name" : "INTEGER16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
79     0x0004 : {"name" : "INTEGER32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
80     0x0005 : {"name" : "UNSIGNED8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []},
81     0x0006 : {"name" : "UNSIGNED16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []},
82     0x0007 : {"name" : "UNSIGNED32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []},
83     0x0008 : {"name" : "REAL32", "struct" : nosub, "size" : 32, "default" : 0.0, "values" : []},
84     0x0009 : {"name" : "VISIBLE_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
85     0x000A : {"name" : "OCTET_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []},
86     0x000B : {"name" : "UNICODE_STRING", "struct" : nosub, "size" : 16, "default" : "", "values" : []},
87 #    0x000C : {"name" : "TIME_OF_DAY", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
88 #    0x000D : {"name" : "TIME_DIFFERENCE", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
89     0x000F : {"name" : "DOMAIN", "struct" : nosub, "size" : 0, "default" : "", "values" : []},
90     0x0010 : {"name" : "INTEGER24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
91     0x0011 : {"name" : "REAL64", "struct" : nosub, "size" : 64, "default" : 0.0, "values" : []},
92     0x0012 : {"name" : "INTEGER40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
93     0x0013 : {"name" : "INTEGER48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
94     0x0014 : {"name" : "INTEGER56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
95     0x0015 : {"name" : "INTEGER64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
96     0x0016 : {"name" : "UNSIGNED24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []},
97     0x0018 : {"name" : "UNSIGNED40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []},
98     0x0019 : {"name" : "UNSIGNED48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []},
99     0x001A : {"name" : "UNSIGNED56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []},
100     0x001B : {"name" : "UNSIGNED64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []},
101     0x1000 : {"name" : "Device Type", "struct" : var, "need" : True, "values" : 
102                 [{"name" : "Device Type", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
103     0x1001 : {"name" : "Error Register", "struct" : var,  "need" : True, "values" : 
104                 [{"name" : "Error Register", "type" : 0x05, "access": 'ro', "pdo" : True}]},
105     0x1002 : {"name" : "Manufacturer Status Register", "struct" : var, "need" : False,  "values" :
106                 [{"name" : "Manufacturer Status Register", "type" : 0x07, "access" : 'ro', "pdo" : True}]},
107     0x1003 : {"name" : "Pre-defined Error Field", "struct" : rec, "need" : False, "callback" : True,  "values" :
108                 [{"name" : "Number of Errors", "type" : 0x05, "access" : 'rw', "pdo" : False},
109                  {"name" : "Standard Error Field", "type" : 0x07, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]},
110     0x1005 : {"name" : "SYNC COB ID", "struct" : var, "need" : False, "callback" : True, "values" :
111                 [{"name" : "SYNC COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
112     0x1006 : {"name" : "Communication / Cycle Period", "struct" : var, "need" : False, "callback" : True, "values" :
113                 [{"name" : "Communication Cycle Period", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
114     0x1007 : {"name" : "Synchronous Window Length", "struct" : var, "need" : False, "values" :
115                 [{"name" : "Synchronous Window Length", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
116     0x1008 : {"name" : "Manufacturer Device Name", "struct" : var, "need" : False, "values" :
117                 [{"name" : "Manufacturer Device Name", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
118     0x1009 : {"name" : "Manufacturer Hardware Version", "struct" : var, "need" : False, "values" :
119                 [{"name" : "Manufacturer Hardware Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
120     0x100A : {"name" : "Manufacturer Software Version", "struct" : var, "need" : False, "values" :
121                 [{"name" : "Manufacturer Software Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]},
122     0x100C : {"name" : "Guard Time", "struct" : var, "need" : False, "values" :
123                 [{"name" : "Guard Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
124     0x100D : {"name" : "Life Time Factor", "struct" : var, "need" : False, "values" :
125                 [{"name" : "Life Time Factor", "type" : 0x05, "access" : 'rw', "pdo" : False}]},
126     0x1010 : {"name" : "Store parameters", "struct" : array, "need" : False, "values" :
127                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
128                  {"name" : "Save All Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
129                  {"name" : "Save Communication Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
130                  {"name" : "Save Application Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
131                  {"name" : "Save Manufacturer Parameters %d[(sub - 3)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
132     0x1011 : {"name" : "Restore Default Parameters", "struct" : array, "need" : False, "values" :
133                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
134                  {"name" : "Restore All Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
135                  {"name" : "Restore Communication Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
136                  {"name" : "Restore Application Default Parameters", "type" : 0x07, "access" : 'rw', "pdo" : False},
137                  {"name" : "Restore Manufacturer Defined Default Parameters %d[(sub - 3)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]},
138     0x1012 : {"name" : "TIME COB ID", "struct" : var, "need" : False, "values" :
139                 [{"name" : "TIME COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False}]},
140     0x1013 : {"name" : "High Resolution Timestamp", "struct" : var, "need" : False, "values" :
141                 [{"name" : "High Resolution Time Stamp", "type" : 0x07, "access" : 'rw', "pdo" : True}]},
142     0x1014 : {"name" : "Emergency COB ID", "struct" : var, "need" : False, "values" :
143                 [{"name" : "Emergency COB ID", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "\"$NODEID+0x80\""}]},
144     0x1015 : {"name" : "Inhibit Time Emergency", "struct" : var, "need" : False, "values" :
145                 [{"name" : "Inhibit Time Emergency", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
146     0x1016 : {"name" : "Consumer Heartbeat Time", "struct" : rec, "need" : False, "values" :
147                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
148                  {"name" : "Consumer Heartbeat Time", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 1, "nbmax" : 0x7F}]},
149     0x1017 : {"name" : "Producer Heartbeat Time", "struct" : var, "need" : False, "callback" : True, "values" :
150                 [{"name" : "Producer Heartbeat Time", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
151     0x1018 : {"name" : "Identity", "struct" : array, "need" : True, "values" :
152                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
153                  {"name" : "Vendor ID", "type" : 0x07, "access" : 'ro', "pdo" : False},
154                  {"name" : "Product Code", "type" : 0x07, "access" : 'ro', "pdo" : False},
155                  {"name" : "Revision Number", "type" : 0x07, "access" : 'ro', "pdo" : False},
156                  {"name" : "Serial Number", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
157     0x1020 : {"name" : "Verify Configuration", "struct" : array, "need" : False, "values" :
158                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
159                  {"name" : "Configuration Date", "type" : 0x07, "access" : 'ro', "pdo" : False},
160                  {"name" : "Configuration Time", "type" : 0x07, "access" : 'ro', "pdo" : False}]},
161 #    0x1021 : {"name" : "Store EDS", "struct" : var, "need" : False, "values" :
162 #                [{"name" : "Store EDS", "type" : 0x0F, "access" : 'rw', "pdo" : False}]},
163 #    0x1022 : {"name" : "Storage Format", "struct" : var, "need" : False, "values" :
164 #                [{"name" : "Storage Format", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
165     0x1023 : {"name" : "OS Command", "struct" : array, "need" : False, "values" :
166                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
167                  {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
168                  {"name" : "Status", "type" : 0x05, "access" : 'ro', "pdo" : False},
169                  {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
170     0x1024 : {"name" : "OS Command Mode", "struct" : var, "need" : False, "values" :
171                 [{"name" : "OS Command Mode", "type" : 0x05, "access" : 'wo', "pdo" : False}]},
172     0x1025 : {"name" : "OS Debugger Interface", "struct" : array, "need" : False, "values" :
173                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
174                  {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False},
175                  {"name" : "Status", "type" : 0x07, "access" : 'ro', "pdo" : False},
176                  {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]},
177     0x1026 : {"name" : "OS Prompt", "struct" : array, "need" : False, "values" :
178                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
179                  {"name" : "StdIn", "type" : 0x05, "access" : 'wo', "pdo" : True},
180                  {"name" : "StdOut", "type" : 0x05, "access" : 'ro', "pdo" : True},
181                  {"name" : "StdErr", "type" : 0x05, "access" : 'ro', "pdo" : True}]},
182     0x1027 : {"name" : "Module List", "struct" : rec, "need" : False, "values" :
183                 [{"name" : "Number of Connected Modules", "type" : 0x05, "access" : 'ro', "pdo" : False},
184                  {"name" : "Module %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : False, "nbmin" : 1, "nbmax" : 0xFE}]},
185     0x1028 : {"name" : "Emergency Consumer", "struct" : rec, "need" : False, "values" :
186                 [{"name" : "Number of Consumed Emergency Objects", "type" : 0x05, "access" : 'ro', "pdo" : False},
187                  {"name" : "Emergency Consumer", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 1, "nbmax" : 0x7E}]},
188     0x1029 : {"name" : "Error Behavior", "struct" : array, "need" : False, "values" :
189                 [{"name" : "Number of Error Classes", "type" : 0x05, "access" : 'ro', "pdo" : False},
190                  {"name" : "Communication Error", "type" : 0x05, "access" : 'rw', "pdo" : False},
191                  {"name" : "Device Profile", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]},
192     0x1200 : {"name" : "Server SDO Parameter", "struct" : array, "need" : False, "values" :
193                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
194                  {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False, "default" : "\"$NODEID+0x600\""},
195                  {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False, "default" : "\"$NODEID+0x580\""}]},
196     0x1201 : {"name" : "Additional Server SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x7F, "need" : False, "values" :
197                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
198                  {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
199                  {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x07, "access" : 'ro', "pdo" : False},
200                  {"name" : "Node ID of the SDO Client", "type" : 0x05, "access" : 'ro', "pdo" : False}]},
201     0x1280 : {"name" : "Client SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x100, "need" : False, "values" :
202                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False},
203                  {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
204                  {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
205                  {"name" : "Node ID of the SDO Server", "type" : 0x05, "access" : 'rw', "pdo" : False}]},
206     0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
207                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
208                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:\"$NODEID+0x%X00\"%(base+2),False:0x80000000}[base<4]"},
209                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
210                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
211                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
212                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
213     0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
214                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
215                  {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 0, "nbmax" : 0x40}]},
216     0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "callback" : True, "values" :
217                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
218                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:\"$NODEID+0x%X80\"%(base+1),False:0x80000000}[base<4]"},
219                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
220                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
221                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
222                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
223     0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
224                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
225                  {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmin" : 0, "nbmax" : 0x40}]},
226 }
227
228 #-------------------------------------------------------------------------------
229 #                         Search in a Mapping Dictionary
230 #-------------------------------------------------------------------------------
231
232 """
233 Return the index of the typename given by searching in mappingdictionary 
234 """
235 def FindTypeIndex(typename, mappingdictionary):
236     testdic = {}
237     for index, values in mappingdictionary.iteritems():
238         if index < 0x1000:
239             testdic[values["name"]] = index
240     if typename in testdic:
241         return testdic[typename]
242     return None
243
244 """
245 Return the name of the type by searching in mappingdictionary 
246 """
247 def FindTypeName(typeindex, mappingdictionary):
248     if typeindex < 0x1000 and typeindex in mappingdictionary:
249         return mappingdictionary[typeindex]["name"]
250     return None
251
252 """
253 Return the default value of the type by searching in mappingdictionary 
254 """
255 def FindTypeDefaultValue(typeindex, mappingdictionary):
256     if typeindex < 0x1000 and typeindex in mappingdictionary:
257         return mappingdictionary[typeindex]["default"]
258     return None
259
260 """
261 Return the list of types defined in mappingdictionary 
262 """
263 def FindTypeList(mappingdictionary):
264     list = []
265     for index in mappingdictionary.keys():
266         if index < 0x1000:
267             list.append(mappingdictionary[index]["name"])
268     return list
269
270 """
271 Return the name of an entry by searching in mappingdictionary 
272 """
273 def FindEntryName(index, mappingdictionary):
274     base_index = FindIndex(index, mappingdictionary)
275     if base_index:
276         infos = mappingdictionary[base_index]
277         if infos["struct"] & OD_IdenticalIndexes:
278             return StringFormat(infos["name"], (index - base_index) / infos["incr"] + 1, 0)
279         else:
280             return infos["name"]
281     return None
282
283 """
284 Return the informations of one entry by searching in mappingdictionary 
285 """
286 def FindEntryInfos(index, mappingdictionary):
287     base_index = FindIndex(index, mappingdictionary)
288     if base_index:
289         copy = mappingdictionary[base_index].copy()
290         if copy["struct"] & OD_IdenticalIndexes:
291             copy["name"] = StringFormat(copy["name"], (index - base_index) / copy["incr"] + 1, 0)
292         copy.pop("values")
293         return copy
294     return None
295
296 """
297 Return the informations of one subentry of an entry by searching in mappingdictionary 
298 """
299 def FindSubentryInfos(index, subIndex, mappingdictionary):
300     base_index = FindIndex(index, mappingdictionary)
301     if base_index:
302         struct = mappingdictionary[base_index]["struct"]
303         if struct & OD_IdenticalIndexes:
304             incr = mappingdictionary[base_index]["incr"]
305         else:
306             incr = 1
307         if struct & OD_Subindex:
308             infos = None
309             if struct & OD_IdenticalSubindexes:
310                 if subIndex == 0:
311                     infos = mappingdictionary[base_index]["values"][0].copy()
312                 elif 0 < subIndex <= mappingdictionary[base_index]["values"][1]["nbmax"]:
313                     infos = mappingdictionary[base_index]["values"][1].copy()
314             elif struct & OD_MultipleSubindexes:
315                 idx = 0
316                 for subindex_infos in mappingdictionary[base_index]["values"]:
317                     if "nbmax" in subindex_infos:
318                         if idx <= subIndex < idx + subindex_infos["nbmax"]:
319                             infos = subindex_infos.copy()
320                             break;
321                         idx += subindex_infos["nbmax"]
322                     else:
323                         if subIndex == idx:
324                             infos = subindex_infos.copy()
325                             break;
326                         idx += 1
327             elif subIndex == 0:
328                 infos = mappingdictionary[base_index]["values"][0].copy()
329             if infos is not None:
330                 infos["name"] = StringFormat(infos["name"], (index - base_index) / incr + 1, subIndex)
331             return infos
332     return None
333
334 """
335 Return the list of variables that can be mapped defined in mappingdictionary 
336 """
337 def FindMapVariableList(mappingdictionary, Node):
338     list = []
339     for index in mappingdictionary.iterkeys():
340         if Node.IsEntry(index):
341             for subIndex, values in enumerate(mappingdictionary[index]["values"]):
342                 if mappingdictionary[index]["values"][subIndex]["pdo"]:
343                     infos = Node.GetEntryInfos(mappingdictionary[index]["values"][subIndex]["type"])
344                     if mappingdictionary[index]["struct"] & OD_IdenticalSubindexes:
345                         values = Node.GetEntry(index)
346                         for i in xrange(len(values) - 1):
347                             list.append((index, i + 1, infos["size"], StringFormat(mappingdictionary[index]["values"][subIndex]["name"],1,i+1)))
348                     else:
349                         list.append((index, subIndex, infos["size"], mappingdictionary[index]["values"][subIndex]["name"]))
350     return list
351
352 """
353 Return the list of mandatory indexes defined in mappingdictionary 
354 """
355 def FindMandatoryIndexes(mappingdictionary):
356     list = []
357     for index in mappingdictionary.iterkeys():
358         if index >= 0x1000 and mappingdictionary[index]["need"]:
359             list.append(index)
360     return list
361
362 """
363 Return the index of the informations in the Object Dictionary in case of identical
364 indexes
365 """
366 def FindIndex(index, mappingdictionary):
367     if index in mappingdictionary:
368         return index
369     else:
370         listpluri = [idx for idx in mappingdictionary.keys() if mappingdictionary[idx]["struct"] & OD_IdenticalIndexes]
371         listpluri.sort()
372         for idx in listpluri:
373             nb_max = mappingdictionary[idx]["nbmax"]
374             incr = mappingdictionary[idx]["incr"]
375             if idx < index < idx + incr * nb_max and (index - idx)%incr == 0:
376                 return idx
377     return None
378
379 #-------------------------------------------------------------------------------
380 #                           Formating Name of an Entry
381 #-------------------------------------------------------------------------------
382
383 name_model = re.compile('(.*)\[(.*)\]')
384
385 """
386 Format the text given with the index and subindex defined
387 """
388 def StringFormat(text, idx, sub):
389     result = name_model.match(text)
390     if result:
391         format = result.groups()
392         return format[0]%eval(format[1])
393     else:
394         return text
395
396 #-------------------------------------------------------------------------------
397 #                          Definition of Node Object
398 #-------------------------------------------------------------------------------
399
400 """
401 Class recording the Object Dictionary entries. It checks at each modification
402 that the structure of the Object Dictionary stay coherent
403 """
404
405 class Node:
406     
407     DefaultStringSize = 10
408     
409     def __init__(self, name = "", type = "slave", id = 0, description = "", profilename = "DS-301", profile = {}, specificmenu = []):
410         self.Name = name
411         self.Type = type
412         self.ID = id
413         self.Description = description
414         self.ProfileName = profilename
415         self.Profile = profile
416         self.SpecificMenu = specificmenu
417         self.Dictionary = {}
418         self.ParamsDictionary = {}
419         self.DS302 = {}
420         self.UserMapping = {}
421     
422     """
423     Return the node name
424     """
425     def GetNodeName(self):
426         return self.Name
427     
428     """
429     Define the node name
430     """
431     def SetNodeName(self, name):
432         self.Name = name
433
434     """
435     Return the node type ("master" or "slave")
436     """
437     def GetNodeType(self):
438         return self.Type
439     
440     """
441     Define the node type ("master" or "slave")
442     """
443     def SetNodeType(self, type):
444         self.Type = type
445
446     """
447     Return the node ID
448     """
449     def GetNodeID(self):
450         return self.ID
451     
452     """
453     Define the node ID
454     """
455     def SetNodeID(self, id):
456         self.ID = id
457
458     """
459     Return the node description
460     """
461     def GetNodeDescription(self):
462         if getattr(self, "Description", False):
463             return self.Description
464         else:
465             return ""
466     
467     """
468     Define the node description
469     """
470     def SetNodeDescription(self, description):
471         self.Description = description
472
473     """
474     Return the Specific Profile Name
475     """
476     def GetProfileName(self):
477         return self.ProfileName
478     
479     """
480     Define the Specific Profile Name
481     """
482     def SetProfileName(self, profilename):
483         self.ProfileName = profilename
484
485     """
486     Return the Specific Profile
487     """
488     def GetProfile(self):
489         return self.Profile
490     
491     """
492     Define the Specific Profile
493     """
494     def SetProfile(self, profile):
495         self.Profile = profile
496     
497     """
498     Return the default string size
499     """
500     def GetDefaultStringSize(self):
501         return self.DefaultStringSize
502     
503     """
504     Define the default string size
505     """
506     def SetDefaultStringSize(self, size):
507         self.DefaultStringSize = size
508     
509     """
510     Define the DS-302 Profile
511     """
512     def SetDS302Profile(self, profile):
513         self.DS302 = profile
514     
515     """
516     Define the DS-302 Profile
517     """
518     def GetDS302Profile(self):
519         return self.DS302
520     
521     """
522     Return the Specific Menu Entries
523     """
524     def GetSpecificMenu(self):
525         return self.SpecificMenu
526     
527     """
528     Define the Specific Menu Entries
529     """
530     def SetSpecificMenu(self, specificmenu):
531         self.SpecificMenu = specificmenu
532     
533     """
534     Extend the Specific Menu Entries
535     """
536     
537     def ExtendSpecificMenu(self, specificmenu):
538         self.SpecificMenu.extend(specificmenu)
539     
540     """
541     Function which return the different Mappings available for this node
542     """
543     def GetMappings(self, userdefinedtoo = True):
544         if userdefinedtoo:
545             return [self.Profile, self.DS302, self.UserMapping]
546         else:
547             return [self.Profile, self.DS302]
548     
549     """
550     Add a new entry in the Object Dictionary
551     """
552     def AddEntry(self, index, subIndex = None, value = None):
553         if index not in self.Dictionary:
554             if not subIndex:
555                 self.Dictionary[index] = value
556                 return True
557             elif subIndex == 1:
558                 self.Dictionary[index] = [value]
559                 return True
560         elif subIndex > 0 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1:
561             self.Dictionary[index].append(value)
562             return True
563         return False
564
565     """
566     Warning ! Modifies an existing entry in the Object Dictionary. Can't add a new one.
567     """
568     def SetEntry(self, index, subIndex = None, value = None):
569         if index in self.Dictionary:
570             if not subIndex:
571                 if value != None:
572                     self.Dictionary[index] = value
573                 return True
574             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
575                 if value != None:
576                     self.Dictionary[index][subIndex - 1] = value
577                 return True
578         return False
579     
580     def SetParamsEntry(self, index, subIndex = None, comment = None, save = None, callback = None):
581         if not getattr(self, "ParamsDictionary", False):
582             self.ParamsDictionary = {}
583         if index in self.Dictionary:
584             if (comment != None or save != None or callback != None) and index not in self.ParamsDictionary:
585                 self.ParamsDictionary[index] = {}
586             if subIndex == None or type(self.Dictionary[index]) != ListType and subIndex == 0:
587                 if comment != None:
588                     self.ParamsDictionary[index]["comment"] = comment
589                 if save != None:
590                     self.ParamsDictionary[index]["save"] = save
591                 if callback != None:
592                     self.ParamsDictionary[index]["callback"] = callback
593                 return True
594             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
595                 if (comment != None or save != None or callback != None) and subIndex not in self.ParamsDictionary[index]:
596                     self.ParamsDictionary[index][subIndex] = {}
597                 if comment != None:
598                     self.ParamsDictionary[index][subIndex]["comment"] = comment
599                 if save != None:
600                     self.ParamsDictionary[index][subIndex]["save"] = save
601                 return True
602         return False
603     
604     """
605     Removes an existing entry in the Object Dictionary. If a subIndex is specified
606     it will remove this subIndex only if it's the last of the index. If no subIndex
607     is specified it removes the whole index and subIndexes from the Object Dictionary.
608     """
609     def RemoveEntry(self, index, subIndex = None):
610         if not getattr(self, "ParamsDictionary", False):
611             self.ParamsDictionary = {}
612         if index in self.Dictionary:
613             if not subIndex:
614                 self.Dictionary.pop(index)
615                 if index in self.ParamsDictionary:
616                     self.ParamsDictionary.pop(index)
617                 return True
618             elif type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]):
619                 self.Dictionary[index].pop(subIndex - 1)
620                 if index in self.ParamsDictionary:
621                     if subIndex in self.ParamsDictionary[index]:
622                         self.ParamsDictionary[index].pop(subIndex)
623                     if len(self.ParamsDictionary[index]) == 0:
624                         self.ParamsDictionary.pop(index)
625                 if len(self.Dictionary[index]) == 0:
626                     self.Dictionary.pop(index)
627                     if index in self.ParamsDictionary:
628                         self.ParamsDictionary.pop(index)
629                 return True
630         return False
631     
632     """
633     Check if an entry exists in the Object Dictionary and returns the answer.
634     """
635     def IsEntry(self, index, subIndex = None):
636         if index in self.Dictionary:
637             if not subIndex:
638                 return True
639             return subIndex <= len(self.Dictionary[index])
640         return False
641     
642     """
643     Returns the value of the entry asked. If the entry has the value "count", it
644     returns the number of subIndex in the entry except the first.
645     """
646     def GetEntry(self, index, subIndex = None, compute = True):
647         if index in self.Dictionary:
648             if subIndex == None:
649                 if type(self.Dictionary[index]) == ListType:
650                     values = [len(self.Dictionary[index])]
651                     for value in self.Dictionary[index]:
652                         values.append(self.CompileValue(value, index, compute))
653                     return values
654                 else:
655                     return self.CompileValue(self.Dictionary[index], index, compute)
656             elif subIndex == 0:
657                 if type(self.Dictionary[index]) == ListType:
658                     return len(self.Dictionary[index])
659                 else:
660                     return self.CompileValue(self.Dictionary[index], index, compute)
661             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
662                 return self.CompileValue(self.Dictionary[index][subIndex - 1], index, compute)
663         return None
664
665     """
666     Returns the value of the entry asked. If the entry has the value "count", it
667     returns the number of subIndex in the entry except the first.
668     """
669     def GetParamsEntry(self, index, subIndex = None):
670         if not getattr(self, "ParamsDictionary", False):
671             self.ParamsDictionary = {}
672         if index in self.Dictionary:
673             if subIndex == None:
674                 if type(self.Dictionary[index]) == ListType:
675                     if index in self.ParamsDictionary:
676                         result = []
677                         for i in xrange(len(self.Dictionary[index]) + 1):
678                             line = DefaultParams.copy()
679                             if i in self.ParamsDictionary[index]:
680                                 line.update(self.ParamsDictionary[index][i])
681                             result.append(line)
682                         return result
683                     else:
684                         return [DefaultParams.copy() for i in xrange(len(self.Dictionary[index]) + 1)]
685                 else:
686                     result = DefaultParams.copy()
687                     if index in self.ParamsDictionary:
688                         result.update(self.ParamsDictionary[index])
689                     return result
690             elif subIndex == 0 and type(self.Dictionary[index]) != ListType:
691                 result = DefaultParams.copy()
692                 if index in self.ParamsDictionary:
693                     result.update(self.ParamsDictionary[index])
694                 return result
695             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
696                 result = DefaultParams.copy()
697                 if index in self.ParamsDictionary and subIndex in self.ParamsDictionary[index]:
698                     result.update(self.ParamsDictionary[index][subIndex])
699                 return result
700         return None
701
702     def HasEntryCallbacks(self, index):
703         entry_infos = self.GetEntryInfos(index)
704         if entry_infos and "callback" in entry_infos:
705             return entry_infos["callback"]
706         else:
707             if not getattr(self, "ParamsDictionary", False):
708                 self.ParamsDictionary = {}
709             if index in self.Dictionary and index in self.ParamsDictionary and "callback" in self.ParamsDictionary[index]:
710                 return self.ParamsDictionary[index]["callback"]
711         return False
712
713     """
714     Check if an entry exists in the User Mapping Dictionary and returns the answer.
715     """
716     def IsMappingEntry(self, index):
717         if index in self.UserMapping:
718             return True
719         return False
720
721     """
722     Add a new entry in the User Mapping Dictionary
723     """
724     def AddMappingEntry(self, index, subIndex = None, name = "Undefined", struct = 0, size = None, nbmax = None, default = None, values = None):
725         if index not in self.UserMapping:
726             if values == None:
727                 values = []
728             if subIndex == None:
729                 self.UserMapping[index] = {"name" : name, "struct" : struct, "need" : False, "values" : values}
730                 if size != None:
731                     self.UserMapping[index]["size"] = size
732                 if nbmax != None:
733                     self.UserMapping[index]["nbmax"] = nbmax
734                 if default != None:
735                     self.UserMapping[index]["default"] = default
736                 return True
737         elif subIndex != None and subIndex == len(self.UserMapping[index]["values"]):
738             if values == None:
739                 values = {}
740             self.UserMapping[index]["values"].append(values)
741             return True
742         return False
743
744     """
745     Warning ! Modifies an existing entry in the User Mapping Dictionary. Can't add a new one.
746     """
747     def SetMappingEntry(self, index, subIndex = None, name = None, struct = None, size = None, nbmax = None, default = None, values = None):
748         if index in self.UserMapping:
749             if subIndex == None:
750                 if name != None:
751                     self.UserMapping[index]["name"] = name
752                     if self.UserMapping[index]["struct"] & OD_IdenticalSubindexes:
753                         self.UserMapping[index]["values"][1]["name"] = name + " %d[(sub)]"
754                     elif not self.UserMapping[index]["struct"] & OD_MultipleSubindexes:
755                         self.UserMapping[index]["values"][0]["name"] = name
756                 if struct != None:
757                     self.UserMapping[index]["struct"] = struct
758                 if size != None:
759                     self.UserMapping[index]["size"] = size
760                 if nbmax != None:
761                     self.UserMapping[index]["nbmax"] = nbmax
762                 if default != None:
763                     self.UserMapping[index]["default"] = default
764                 if values != None:
765                     self.UserMapping[index]["values"] = values
766                 return True
767             elif 0 <= subIndex < len(self.UserMapping[index]["values"]) and values != None:
768                 if "type" in values:
769                     if self.UserMapping[index]["struct"] & OD_IdenticalSubindexes:
770                         if self.IsStringType(self.UserMapping[index]["values"][subIndex]["type"]):
771                             if self.IsRealType(values["type"]):
772                                 for i in xrange(len(self.Dictionary[index])):
773                                     self.SetEntry(index, i + 1, 0.)
774                             elif not self.IsStringType(values["type"]):
775                                 for i in xrange(len(self.Dictionary[index])):
776                                     self.SetEntry(index, i + 1, 0)
777                         elif self.IsRealType(self.UserMapping[index]["values"][subIndex]["type"]):
778                             if self.IsStringType(values["type"]):
779                                 for i in xrange(len(self.Dictionary[index])):
780                                     self.SetEntry(index, i + 1, "")
781                             elif not self.IsRealType(values["type"]):
782                                 for i in xrange(len(self.Dictionary[index])):
783                                     self.SetEntry(index, i + 1, 0)
784                         elif self.IsStringType(values["type"]):
785                             for i in xrange(len(self.Dictionary[index])):
786                                 self.SetEntry(index, i + 1, "")
787                         elif self.IsRealType(values["type"]):
788                             for i in xrange(len(self.Dictionary[index])):
789                                 self.SetEntry(index, i + 1, 0.)                        
790                     else:
791                         if self.IsStringType(self.UserMapping[index]["values"][subIndex]["type"]):
792                             if self.IsRealType(values["type"]):
793                                 self.SetEntry(index, subIndex, 0.)
794                             elif not self.IsStringType(values["type"]):
795                                 self.SetEntry(index, subIndex, 0)
796                         elif self.IsRealType(self.UserMapping[index]["values"][subIndex]["type"]):
797                             if self.IsStringType(values["type"]):
798                                 self.SetEntry(index, subIndex, "")
799                             elif not self.IsRealType(values["type"]):
800                                 self.SetEntry(index, subIndex, 0)
801                         elif self.IsStringType(values["type"]):
802                             self.SetEntry(index, subIndex, "")
803                         elif self.IsRealType(values["type"]):
804                             self.SetEntry(index, subIndex, 0.)
805                 self.UserMapping[index]["values"][subIndex].update(values)
806                 return True
807         return False
808     
809     """
810     Removes an existing entry in the User Mapping Dictionary. If a subIndex is specified
811     it will remove this subIndex only if it's the last of the index. If no subIndex
812     is specified it removes the whole index and subIndexes from the User Mapping Dictionary.
813     """
814     def RemoveMappingEntry(self, index, subIndex = None):
815         if index in self.UserMapping:
816             if subIndex == None:
817                 self.UserMapping.pop(index)
818                 return True
819             elif subIndex == len(self.UserMapping[index]["values"]) - 1:
820                 self.UserMapping[index]["values"].pop(subIndex)
821                 return True
822         return False
823
824     def RemoveMapVariable(self, index, subIndex = None):
825         model = index << 16
826         mask = 0xFFFF << 16
827         if subIndex:
828             model += subIndex << 8
829             mask += 0xFF << 8
830         for i in self.Dictionary.iterkeys():
831             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
832                 for j,value in enumerate(self.Dictionary[i]):
833                     if (value & mask) == model:
834                         self.Dictionary[i][j] = 0
835     
836     def UpdateMapVariable(self, index, subIndex, size):
837         model = index << 16
838         mask = 0xFFFF << 16
839         if subIndex:
840             model += subIndex << 8
841             mask = 0xFF << 8
842         for i in self.Dictionary.iterkeys():
843             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
844                 for j,value in enumerate(self.Dictionary[i]):
845                     if (value & mask) == model:
846                         self.Dictionary[i][j] = model + size
847     
848     def RemoveLine(self, index, max, incr = 1):
849         i = index
850         while i < max and self.IsEntry(i + incr):
851             self.Dictionary[i] = self.Dictionary[i + incr]
852             i += incr
853         self.Dictionary.pop(i)
854
855     def RemoveUserType(self, index):
856         type = self.GetEntry(index, 1)
857         for i in self.UserMapping:
858             for value in self.UserMapping[i]["values"]:
859                 if value["type"] == index:
860                     value["type"] = type
861         self.RemoveMappingEntry(index)
862         self.RemoveEntry(index)
863
864     """
865     Return a copy of the node
866     """
867     def Copy(self):
868         return cPickle.loads(cPickle.dumps(self))
869
870     """
871     Return a sorted list of indexes in Object Dictionary
872     """
873     def GetIndexes(self):
874         listindex = self.Dictionary.keys()
875         listindex.sort()
876         return listindex
877
878     """
879     Print the Dictionary values
880     """
881     def Print(self):
882         print self.PrintString()
883     
884     def PrintString(self):
885         result = ""
886         listindex = self.Dictionary.keys()
887         listindex.sort()
888         for index in listindex:
889             name = self.GetEntryName(index)
890             values = self.Dictionary[index]
891             if isinstance(values, ListType):
892                 result += "%04X (%s):\n"%(index, name)
893                 for subidx, value in enumerate(values):
894                     subentry_infos = self.GetSubentryInfos(index, subidx + 1)
895                     if index == 0x1F22 and value:
896                         nb_params = BE_to_LE(value[:4])
897                         data = value[4:]
898                         value = "%d arg defined"%nb_params
899                         i = 0
900                         count = 1
901                         while i < len(data):
902                             value += "\n%04X %02X, arg %d: "%(index, subidx+1, count)
903                             value += "%04X"%BE_to_LE(data[i:i+2])
904                             value += " %02X"%BE_to_LE(data[i+2:i+3])
905                             size = BE_to_LE(data[i+3:i+7])
906                             value += " %08X"%size
907                             value += (" %0"+"%d"%(size * 2)+"X")%BE_to_LE(data[i+7:i+7+size])
908                             i += 7 + size
909                             count += 1
910                     elif isinstance(value, IntType):
911                         value = "%X"%value
912                     result += "%04X %02X (%s): %s\n"%(index, subidx+1, subentry_infos["name"], value)
913             else:
914                 if isinstance(values, IntType):
915                     values = "%X"%values
916                 result += "%04X (%s): %s\n"%(index, name, values)
917         return result
918             
919     def CompileValue(self, value, index, compute = True):
920         if isinstance(value, (StringType, UnicodeType)) and value.find("$NODEID") != -1:
921             base = self.GetBaseIndex(index)
922             try:
923                 raw = eval(value)
924                 if compute:
925                     return eval(raw.upper().replace("$NODEID","self.ID"))
926                 return raw
927             except:
928                 return 0
929         else:
930             return value
931
932 #-------------------------------------------------------------------------------
933 #                         Node Informations Functions
934 #-------------------------------------------------------------------------------
935
936     def GetBaseIndex(self, index):
937         for mapping in self.GetMappings():
938             result = FindIndex(index, mapping)
939             if result != None:
940                 return (index - result) / mapping[result].get("incr", 1)
941         result = FindIndex(index, MappingDictionary)
942         if result != None:
943             return (index - result) / MappingDictionary[result].get("incr", 1)
944         return 0
945
946     def GetCustomisedTypeValues(self, index):
947         values = self.GetEntry(index)
948         customisabletypes = self.GetCustomisableTypes()
949         return values, customisabletypes[values[1]][1]
950
951     def GetEntryName(self, index):
952         result = None
953         mappings = self.GetMappings()
954         i = 0
955         while not result and i < len(mappings):
956             result = FindEntryName(index, mappings[i])
957             i += 1
958         if result == None:
959             result = FindEntryName(index, MappingDictionary)
960         return result
961     
962     def GetEntryInfos(self, index):
963         result = None
964         mappings = self.GetMappings()
965         i = 0
966         while not result and i < len(mappings):
967             result = FindEntryInfos(index, mappings[i])
968             i += 1
969         if result == None:
970             result = FindEntryInfos(index, MappingDictionary)
971         return result
972     
973     def GetSubentryInfos(self, index, subIndex):
974         result = None
975         mappings = self.GetMappings()
976         i = 0
977         while not result and i < len(mappings):
978             result = FindSubentryInfos(index, subIndex, mappings[i])
979             if result:
980                 result["user_defined"] = i == len(mappings) - 1 and index >= 0x1000
981             i += 1
982         if result == None:
983             result = FindSubentryInfos(index, subIndex, MappingDictionary)
984             if result:
985                 result["user_defined"] = False
986         return result
987     
988     def GetTypeIndex(self, typename):
989         result = None
990         mappings = self.GetMappings()
991         i = 0
992         while not result and i < len(mappings):
993             result = FindTypeIndex(typename, mappings[i])
994             i += 1
995         if result == None:
996             result = FindTypeIndex(typename, MappingDictionary)
997         return result
998     
999     def GetTypeName(self, typeindex):
1000         result = None
1001         mappings = self.GetMappings()
1002         i = 0
1003         while not result and i < len(mappings):
1004             result = FindTypeName(typeindex, mappings[i])
1005             i += 1
1006         if result == None:
1007             result = FindTypeName(typeindex, MappingDictionary)
1008         return result
1009     
1010     def GetTypeDefaultValue(self, typeindex):
1011         result = None
1012         mappings = self.GetMappings()
1013         i = 0
1014         while not result and i < len(mappings):
1015             result = FindTypeDefaultValue(typeindex, mappings[i])
1016             i += 1
1017         if result == None:
1018             result = FindTypeDefaultValue(typeindex, MappingDictionary)
1019         return result
1020     
1021     def GetMapVariableList(self):
1022         list = FindMapVariableList(MappingDictionary, self)
1023         for mapping in self.GetMappings():
1024             list.extend(FindMapVariableList(mapping, self))
1025         list.sort()
1026         return list
1027     
1028     def GetMandatoryIndexes(self, node = None):
1029         list = FindMandatoryIndexes(MappingDictionary)
1030         for mapping in self.GetMappings():
1031             list.extend(FindMandatoryIndexes(mapping))
1032         return list
1033     
1034     def GetCustomisableTypes(self):
1035         dic = {}
1036         for index, valuetype in CustomisableTypes:
1037             name = self.GetTypeName(index)
1038             dic[index] = [name, valuetype]
1039         return dic
1040
1041 #-------------------------------------------------------------------------------
1042 #                            Type helper functions
1043 #-------------------------------------------------------------------------------
1044
1045     def IsStringType(self, index):
1046         if index in (0x9, 0xA, 0xB, 0xF):
1047             return True
1048         elif 0xA0 <= index < 0x100:
1049             result = self.GetEntry(index, 1)
1050             if result is not None and result in (0x9, 0xA, 0xB):
1051                 return True
1052         return False
1053
1054     def IsRealType(self, index):
1055         if index in (0x8, 0x11):
1056             return True
1057         elif 0xA0 <= index < 0x100:
1058             result = self.GetEntry(index, 1)
1059             if result is not None and result in (0x8, 0x11):
1060                 return True
1061         return False
1062
1063 #-------------------------------------------------------------------------------
1064 #                            Type and Map Variable Lists
1065 #-------------------------------------------------------------------------------
1066     
1067     def GetTypeList(self):
1068         list = FindTypeList(MappingDictionary)
1069         for mapping in self.GetMappings():
1070             list.extend(FindTypeList(mapping))
1071         list.sort()
1072         return ",".join(list)
1073
1074     """
1075     Generate the list of variables that can be mapped for the current node
1076     """
1077     def GenerateMapList(self):
1078         self.MapList = "None"
1079         self.NameTranslation = {"None" : "00000000"}
1080         self.MapTranslation = {"00000000" : "None"}
1081         list = self.GetMapVariableList()
1082         for index, subIndex, size, name in list:
1083             self.MapList += ",%s"%name
1084             map = "%04X%02X%02X"%(index,subIndex,size)
1085             self.NameTranslation[name] = map
1086             self.MapTranslation[map] = name
1087
1088     def GetMapValue(self, mapname):
1089         if mapname == "None":
1090             return 0
1091         else:
1092             list = self.GetMapVariableList()
1093             for index, subIndex, size, name in list:
1094                 if mapname == name:
1095                     return (index << 16) + (subIndex << 8) + size
1096             return None
1097     
1098     def GetMapName(self, value):
1099         if value != 0:
1100             index = value >> 16
1101             subindex = (value >> 8) % (1 << 8)
1102             result = self.GetSubentryInfos(index, subindex)
1103             if result:
1104                 return result["name"]
1105         return "None"
1106     
1107     """
1108     Return the list of variables that can be mapped for the current node
1109     """
1110     def GetMapList(self):
1111         list = ["None"] + [name for index, subIndex, size, name in self.GetMapVariableList()]
1112         return ",".join(list)
1113
1114 def BE_to_LE(value):
1115     """
1116     Convert Big Endian to Little Endian 
1117     @param value: value expressed in Big Endian
1118     @param size: number of bytes generated
1119     @return: a string containing the value converted
1120     """
1121     
1122     data = [char for char in value]
1123     data.reverse()
1124     return int("".join(["%2.2X"%ord(char) for char in data]), 16)
1125
1126 def LE_to_BE(value, size):
1127     """
1128     Convert Little Endian to Big Endian
1129     @param value: value expressed in integer
1130     @param size: number of bytes generated
1131     @return: a string containing the value converted
1132     """
1133     
1134     data = ("%" + str(size * 2) + "." + str(size * 2) + "X") % value
1135     list_car = [data[i:i+2] for i in xrange(0, len(data), 2)]
1136     list_car.reverse()
1137     return "".join([chr(int(car, 16)) for car in list_car])
1138