]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/node.py
aaf6eeb89c6cfbfc79e7fa230bb7ac1d43e8fbbe
[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", "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 Default Parameters", "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_Subindex:
304             if struct & OD_IdenticalSubindexes:
305                 if struct & OD_IdenticalIndexes:
306                     incr = mappingdictionary[base_index]["incr"]
307                 else:
308                     incr = 1
309                 if subIndex == 0:
310                     return mappingdictionary[base_index]["values"][0].copy()
311                 elif 0 < subIndex <= mappingdictionary[base_index]["values"][1]["nbmax"]:
312                     copy = mappingdictionary[base_index]["values"][1].copy()
313                     copy["name"] = StringFormat(copy["name"], (index - base_index) / incr + 1, subIndex)
314                     return copy
315             elif struct & OD_MultipleSubindexes and 0 <= subIndex < len(mappingdictionary[base_index]["values"]):
316                 return mappingdictionary[base_index]["values"][subIndex].copy()
317             elif subIndex == 0:
318                 return mappingdictionary[base_index]["values"][0].copy()
319     return None
320
321 """
322 Return the list of variables that can be mapped defined in mappingdictionary 
323 """
324 def FindMapVariableList(mappingdictionary, Node):
325     list = []
326     for index in mappingdictionary.iterkeys():
327         if Node.IsEntry(index):
328             for subIndex, values in enumerate(mappingdictionary[index]["values"]):
329                 if mappingdictionary[index]["values"][subIndex]["pdo"]:
330                     infos = Node.GetEntryInfos(mappingdictionary[index]["values"][subIndex]["type"])
331                     if mappingdictionary[index]["struct"] & OD_IdenticalSubindexes:
332                         values = Node.GetEntry(index)
333                         for i in xrange(len(values) - 1):
334                             list.append((index, i + 1, infos["size"], StringFormat(mappingdictionary[index]["values"][subIndex]["name"],1,i+1)))
335                     else:
336                         list.append((index, subIndex, infos["size"], mappingdictionary[index]["values"][subIndex]["name"]))
337     return list
338
339 """
340 Return the list of mandatory indexes defined in mappingdictionary 
341 """
342 def FindMandatoryIndexes(mappingdictionary):
343     list = []
344     for index in mappingdictionary.iterkeys():
345         if index >= 0x1000 and mappingdictionary[index]["need"]:
346             list.append(index)
347     return list
348
349 """
350 Return the index of the informations in the Object Dictionary in case of identical
351 indexes
352 """
353 def FindIndex(index, mappingdictionary):
354     if index in mappingdictionary:
355         return index
356     else:
357         listpluri = [idx for idx in mappingdictionary.keys() if mappingdictionary[idx]["struct"] & OD_IdenticalIndexes]
358         listpluri.sort()
359         for idx in listpluri:
360             nb_max = mappingdictionary[idx]["nbmax"]
361             incr = mappingdictionary[idx]["incr"]
362             if idx < index < idx + incr * nb_max and (index - idx)%incr == 0:
363                 return idx
364     return None
365
366 #-------------------------------------------------------------------------------
367 #                           Formating Name of an Entry
368 #-------------------------------------------------------------------------------
369
370 name_model = re.compile('(.*)\[(.*)\]')
371
372 """
373 Format the text given with the index and subindex defined
374 """
375 def StringFormat(text, idx, sub):
376     result = name_model.match(text)
377     if result:
378         format = result.groups()
379         return format[0]%eval(format[1])
380     else:
381         return text
382
383 #-------------------------------------------------------------------------------
384 #                          Definition of Node Object
385 #-------------------------------------------------------------------------------
386
387 """
388 Class recording the Object Dictionary entries. It checks at each modification
389 that the structure of the Object Dictionary stay coherent
390 """
391
392 class Node:
393     
394     DefaultStringSize = 10
395     
396     def __init__(self, name = "", type = "slave", id = 0, description = "", profilename = "DS-301", profile = {}, specificmenu = []):
397         self.Name = name
398         self.Type = type
399         self.ID = id
400         self.Description = description
401         self.ProfileName = profilename
402         self.Profile = profile
403         self.SpecificMenu = specificmenu
404         self.Dictionary = {}
405         self.ParamsDictionary = {}
406         self.DS302 = {}
407         self.UserMapping = {}
408     
409     """
410     Return the node name
411     """
412     def GetNodeName(self):
413         return self.Name
414     
415     """
416     Define the node name
417     """
418     def SetNodeName(self, name):
419         self.Name = name
420
421     """
422     Return the node type ("master" or "slave")
423     """
424     def GetNodeType(self):
425         return self.Type
426     
427     """
428     Define the node type ("master" or "slave")
429     """
430     def SetNodeType(self, type):
431         self.Type = type
432
433     """
434     Return the node ID
435     """
436     def GetNodeID(self):
437         return self.ID
438     
439     """
440     Define the node ID
441     """
442     def SetNodeID(self, id):
443         self.ID = id
444
445     """
446     Return the node description
447     """
448     def GetNodeDescription(self):
449         if getattr(self, "Description", False):
450             return self.Description
451         else:
452             return ""
453     
454     """
455     Define the node description
456     """
457     def SetNodeDescription(self, description):
458         self.Description = description
459
460     """
461     Return the Specific Profile Name
462     """
463     def GetProfileName(self):
464         return self.ProfileName
465     
466     """
467     Define the Specific Profile Name
468     """
469     def SetProfileName(self, profilename):
470         self.ProfileName = profilename
471
472     """
473     Return the Specific Profile
474     """
475     def GetProfile(self):
476         return self.Profile
477     
478     """
479     Define the Specific Profile
480     """
481     def SetProfile(self, profile):
482         self.Profile = profile
483     
484     """
485     Return the default string size
486     """
487     def GetDefaultStringSize(self):
488         return self.DefaultStringSize
489     
490     """
491     Define the default string size
492     """
493     def SetDefaultStringSize(self, size):
494         self.DefaultStringSize = size
495     
496     """
497     Define the DS-302 Profile
498     """
499     def SetDS302Profile(self, profile):
500         self.DS302 = profile
501     
502     """
503     Define the DS-302 Profile
504     """
505     def GetDS302Profile(self):
506         return self.DS302
507     
508     """
509     Return the Specific Menu Entries
510     """
511     def GetSpecificMenu(self):
512         return self.SpecificMenu
513     
514     """
515     Define the Specific Menu Entries
516     """
517     def SetSpecificMenu(self, specificmenu):
518         self.SpecificMenu = specificmenu
519     
520     """
521     Extend the Specific Menu Entries
522     """
523     
524     def ExtendSpecificMenu(self, specificmenu):
525         self.SpecificMenu.extend(specificmenu)
526     
527     """
528     Function which return the different Mappings available for this node
529     """
530     def GetMappings(self, userdefinedtoo = True):
531         if userdefinedtoo:
532             return [self.Profile, self.DS302, self.UserMapping]
533         else:
534             return [self.Profile, self.DS302]
535     
536     """
537     Add a new entry in the Object Dictionary
538     """
539     def AddEntry(self, index, subIndex = None, value = None):
540         if index not in self.Dictionary:
541             if not subIndex:
542                 self.Dictionary[index] = value
543                 return True
544             elif subIndex == 1:
545                 self.Dictionary[index] = [value]
546                 return True
547         elif subIndex > 0 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1:
548             self.Dictionary[index].append(value)
549             return True
550         return False
551
552     """
553     Warning ! Modifies an existing entry in the Object Dictionary. Can't add a new one.
554     """
555     def SetEntry(self, index, subIndex = None, value = None):
556         if index in self.Dictionary:
557             if not subIndex:
558                 if value != None:
559                     self.Dictionary[index] = value
560                 return True
561             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
562                 if value != None:
563                     self.Dictionary[index][subIndex - 1] = value
564                 return True
565         return False
566     
567     def SetParamsEntry(self, index, subIndex = None, comment = None, save = None, callback = None):
568         if not getattr(self, "ParamsDictionary", False):
569             self.ParamsDictionary = {}
570         if index in self.Dictionary:
571             if (comment != None or save != None or callback != None) and index not in self.ParamsDictionary:
572                 self.ParamsDictionary[index] = {}
573             if subIndex == None or type(self.Dictionary[index]) != ListType and subIndex == 0:
574                 if comment != None:
575                     self.ParamsDictionary[index]["comment"] = comment
576                 if save != None:
577                     self.ParamsDictionary[index]["save"] = save
578                 if callback != None:
579                     self.ParamsDictionary[index]["callback"] = callback
580                 return True
581             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
582                 if (comment != None or save != None or callback != None) and subIndex not in self.ParamsDictionary[index]:
583                     self.ParamsDictionary[index][subIndex] = {}
584                 if comment != None:
585                     self.ParamsDictionary[index][subIndex]["comment"] = comment
586                 if save != None:
587                     self.ParamsDictionary[index][subIndex]["save"] = save
588                 return True
589         return False
590     
591     """
592     Removes an existing entry in the Object Dictionary. If a subIndex is specified
593     it will remove this subIndex only if it's the last of the index. If no subIndex
594     is specified it removes the whole index and subIndexes from the Object Dictionary.
595     """
596     def RemoveEntry(self, index, subIndex = None):
597         if not getattr(self, "ParamsDictionary", False):
598             self.ParamsDictionary = {}
599         if index in self.Dictionary:
600             if not subIndex:
601                 self.Dictionary.pop(index)
602                 if index in self.ParamsDictionary:
603                     self.ParamsDictionary.pop(index)
604                 return True
605             elif type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]):
606                 self.Dictionary[index].pop(subIndex - 1)
607                 if index in self.ParamsDictionary:
608                     if subIndex in self.ParamsDictionary[index]:
609                         self.ParamsDictionary[index].pop(subIndex)
610                     if len(self.ParamsDictionary[index]) == 0:
611                         self.ParamsDictionary.pop(index)
612                 if len(self.Dictionary[index]) == 0:
613                     self.Dictionary.pop(index)
614                     if index in self.ParamsDictionary:
615                         self.ParamsDictionary.pop(index)
616                 return True
617         return False
618     
619     """
620     Check if an entry exists in the Object Dictionary and returns the answer.
621     """
622     def IsEntry(self, index, subIndex = None):
623         if index in self.Dictionary:
624             if not subIndex:
625                 return True
626             return subIndex <= len(self.Dictionary[index])
627         return False
628     
629     """
630     Returns the value of the entry asked. If the entry has the value "count", it
631     returns the number of subIndex in the entry except the first.
632     """
633     def GetEntry(self, index, subIndex = None, compute = True):
634         if index in self.Dictionary:
635             if subIndex == None:
636                 if type(self.Dictionary[index]) == ListType:
637                     values = [len(self.Dictionary[index])]
638                     for value in self.Dictionary[index]:
639                         values.append(self.CompileValue(value, index, compute))
640                     return values
641                 else:
642                     return self.CompileValue(self.Dictionary[index], index, compute)
643             elif subIndex == 0:
644                 if type(self.Dictionary[index]) == ListType:
645                     return len(self.Dictionary[index])
646                 else:
647                     return self.CompileValue(self.Dictionary[index], index, compute)
648             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
649                 return self.CompileValue(self.Dictionary[index][subIndex - 1], index, compute)
650         return None
651
652     """
653     Returns the value of the entry asked. If the entry has the value "count", it
654     returns the number of subIndex in the entry except the first.
655     """
656     def GetParamsEntry(self, index, subIndex = None):
657         if not getattr(self, "ParamsDictionary", False):
658             self.ParamsDictionary = {}
659         if index in self.Dictionary:
660             if subIndex == None:
661                 if type(self.Dictionary[index]) == ListType:
662                     if index in self.ParamsDictionary:
663                         result = []
664                         for i in xrange(len(self.Dictionary[index]) + 1):
665                             line = DefaultParams.copy()
666                             if i in self.ParamsDictionary[index]:
667                                 line.update(self.ParamsDictionary[index][i])
668                             result.append(line)
669                         return result
670                     else:
671                         return [DefaultParams.copy() for i in xrange(len(self.Dictionary[index]) + 1)]
672                 else:
673                     result = DefaultParams.copy()
674                     if index in self.ParamsDictionary:
675                         result.update(self.ParamsDictionary[index])
676                     return result
677             elif subIndex == 0 and type(self.Dictionary[index]) != ListType:
678                 result = DefaultParams.copy()
679                 if index in self.ParamsDictionary:
680                     result.update(self.ParamsDictionary[index])
681                 return result
682             elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]):
683                 result = DefaultParams.copy()
684                 if index in self.ParamsDictionary and subIndex in self.ParamsDictionary[index]:
685                     result.update(self.ParamsDictionary[index][subIndex])
686                 return result
687         return None
688
689     def HasEntryCallbacks(self, index):
690         entry_infos = self.GetEntryInfos(index)
691         if entry_infos and "callback" in entry_infos:
692             return entry_infos["callback"]
693         else:
694             if not getattr(self, "ParamsDictionary", False):
695                 self.ParamsDictionary = {}
696             if index in self.Dictionary and index in self.ParamsDictionary and "callback" in self.ParamsDictionary[index]:
697                 return self.ParamsDictionary[index]["callback"]
698         return False
699
700     """
701     Check if an entry exists in the User Mapping Dictionary and returns the answer.
702     """
703     def IsMappingEntry(self, index):
704         if index in self.UserMapping:
705             return True
706         return False
707
708     """
709     Add a new entry in the User Mapping Dictionary
710     """
711     def AddMappingEntry(self, index, subIndex = None, name = "Undefined", struct = 0, size = None, nbmax = None, default = None, values = None):
712         if index not in self.UserMapping:
713             if values == None:
714                 values = []
715             if subIndex == None:
716                 self.UserMapping[index] = {"name" : name, "struct" : struct, "need" : False, "values" : values}
717                 if size != None:
718                     self.UserMapping[index]["size"] = size
719                 if nbmax != None:
720                     self.UserMapping[index]["nbmax"] = nbmax
721                 if default != None:
722                     self.UserMapping[index]["default"] = default
723                 return True
724         elif subIndex != None and subIndex == len(self.UserMapping[index]["values"]):
725             if values == None:
726                 values = {}
727             self.UserMapping[index]["values"].append(values)
728             return True
729         return False
730
731     """
732     Warning ! Modifies an existing entry in the User Mapping Dictionary. Can't add a new one.
733     """
734     def SetMappingEntry(self, index, subIndex = None, name = None, struct = None, size = None, nbmax = None, default = None, values = None):
735         if index in self.UserMapping:
736             if subIndex == None:
737                 if name != None:
738                     self.UserMapping[index]["name"] = name
739                     if self.UserMapping[index]["struct"] & OD_IdenticalSubindexes:
740                         self.UserMapping[index]["values"][1]["name"] = name + " %d[(sub)]"
741                     elif not self.UserMapping[index]["struct"] & OD_MultipleSubindexes:
742                         self.UserMapping[index]["values"][0]["name"] = name
743                 if struct != None:
744                     self.UserMapping[index]["struct"] = struct
745                 if size != None:
746                     self.UserMapping[index]["size"] = size
747                 if nbmax != None:
748                     self.UserMapping[index]["nbmax"] = nbmax
749                 if default != None:
750                     self.UserMapping[index]["default"] = default
751                 if values != None:
752                     self.UserMapping[index]["values"] = values
753                 return True
754             elif 0 <= subIndex < len(self.UserMapping[index]["values"]) and values != None:
755                 if "type" in values:
756                     if self.IsStringType(values["type"]) and not self.IsStringType(self.UserMapping[index]["values"][subIndex]["type"]):
757                         self.SetEntry(index, subIndex, "")
758                     elif not self.IsStringType(values["type"]) and self.IsStringType(self.UserMapping[index]["values"][subIndex]["type"]):
759                         self.SetEntry(index, subIndex, 0)
760                 self.UserMapping[index]["values"][subIndex].update(values)
761                 return True
762         return False
763     
764     """
765     Removes an existing entry in the User Mapping Dictionary. If a subIndex is specified
766     it will remove this subIndex only if it's the last of the index. If no subIndex
767     is specified it removes the whole index and subIndexes from the User Mapping Dictionary.
768     """
769     def RemoveMappingEntry(self, index, subIndex = None):
770         if index in self.UserMapping:
771             if subIndex == None:
772                 self.UserMapping.pop(index)
773                 return True
774             elif subIndex == len(self.UserMapping[index]["values"]) - 1:
775                 self.UserMapping[index]["values"].pop(subIndex)
776                 return True
777         return False
778
779     def RemoveMapVariable(self, index, subIndex = None):
780         model = index << 16
781         mask = 0xFFFF << 16
782         if subIndex:
783             model += subIndex << 8
784             mask += 0xFF << 8
785         for i in self.Dictionary.iterkeys():
786             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
787                 for j,value in enumerate(self.Dictionary[i]):
788                     if (value & mask) == model:
789                         self.Dictionary[i][j] = 0
790     
791     def UpdateMapVariable(self, index, subIndex, size):
792         model = index << 16
793         mask = 0xFFFF << 16
794         if subIndex:
795             model += subIndex << 8
796             mask = 0xFF << 8
797         for i in self.Dictionary.iterkeys():
798             if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF:
799                 for j,value in enumerate(self.Dictionary[i]):
800                     if (value & mask) == model:
801                         self.Dictionary[i][j] = model + size
802     
803     def RemoveLine(self, index, max, incr = 1):
804         i = index
805         while i < max and self.IsEntry(i + incr):
806             self.Dictionary[i] = self.Dictionary[i + incr]
807             i += incr
808         self.Dictionary.pop(i)
809
810     def RemoveUserType(self, index):
811         type = self.GetEntry(index, 1)
812         for i in self.UserMapping:
813             for value in self.UserMapping[i]["values"]:
814                 if value["type"] == index:
815                     value["type"] = type
816         self.RemoveMappingEntry(index)
817         self.RemoveEntry(index)
818
819     """
820     Return a copy of the node
821     """
822     def Copy(self):
823         return cPickle.loads(cPickle.dumps(self))
824
825     """
826     Return a sorted list of indexes in Object Dictionary
827     """
828     def GetIndexes(self):
829         listindex = self.Dictionary.keys()
830         listindex.sort()
831         return listindex
832
833     """
834     Print the Dictionary values
835     """
836     def Print(self):
837         print self.PrintString()
838     
839     def PrintString(self):
840         result = ""
841         listindex = self.Dictionary.keys()
842         listindex.sort()
843         for index in listindex:
844             name = self.GetEntryName(index)
845             values = self.Dictionary[index]
846             if isinstance(values, ListType):
847                 result += "%04X (%s):\n"%(index, name)
848                 for subidx, value in enumerate(values):
849                     subentry_infos = self.GetSubentryInfos(index, subidx + 1)
850                     if index == 0x1F22 and value:
851                         nb_params = BE_to_LE(value[:4])
852                         data = value[4:]
853                         value = "%d arg defined"%nb_params
854                         i = 0
855                         count = 1
856                         while i < len(data):
857                             value += "\n%04X %02X, arg %d: "%(index, subidx+1, count)
858                             value += "%04X"%BE_to_LE(data[i:i+2])
859                             value += " %02X"%BE_to_LE(data[i+2:i+3])
860                             size = BE_to_LE(data[i+3:i+7])
861                             value += " %08X"%size
862                             value += (" %0"+"%d"%(size * 2)+"X")%BE_to_LE(data[i+7:i+7+size])
863                             i += 7 + size
864                             count += 1
865                     elif isinstance(value, IntType):
866                         value = "%X"%value
867                     result += "%04X %02X (%s): %s\n"%(index, subidx+1, subentry_infos["name"], value)
868             else:
869                 if isinstance(values, IntType):
870                     values = "%X"%values
871                 result += "%04X (%s): %s\n"%(index, name, values)
872         return result
873             
874     def CompileValue(self, value, index, compute = True):
875         if type(value) == StringType and value.find("$NODEID") != -1:
876             base = self.GetBaseIndex(index)
877             try:
878                 raw = eval(value)
879                 if compute:
880                     return eval(raw.replace("$NODEID","self.ID"))
881                 return raw
882             except:
883                 return 0
884         else:
885             return value
886
887 #-------------------------------------------------------------------------------
888 #                         Node Informations Functions
889 #-------------------------------------------------------------------------------
890
891     def GetBaseIndex(self, index):
892         for mapping in self.GetMappings():
893             result = FindIndex(index, mapping)
894             if result != None:
895                 return (index - result) / mapping[result].get("incr", 1)
896         result = FindIndex(index, MappingDictionary)
897         if result != None:
898             return (index - result) / MappingDictionary[result].get("incr", 1)
899         return 0
900
901     def GetCustomisedTypeValues(self, index):
902         values = self.GetEntry(index)
903         customisabletypes = self.GetCustomisableTypes()
904         return values, customisabletypes[values[1]][1]
905
906     def GetEntryName(self, index):
907         result = None
908         mappings = self.GetMappings()
909         i = 0
910         while not result and i < len(mappings):
911             result = FindEntryName(index, mappings[i])
912             i += 1
913         if result == None:
914             result = FindEntryName(index, MappingDictionary)
915         return result
916     
917     def GetEntryInfos(self, index):
918         result = None
919         mappings = self.GetMappings()
920         i = 0
921         while not result and i < len(mappings):
922             result = FindEntryInfos(index, mappings[i])
923             i += 1
924         if result == None:
925             result = FindEntryInfos(index, MappingDictionary)
926         return result
927     
928     def GetSubentryInfos(self, index, subIndex):
929         result = None
930         mappings = self.GetMappings()
931         i = 0
932         while not result and i < len(mappings):
933             result = FindSubentryInfos(index, subIndex, mappings[i])
934             if result:
935                 result["user_defined"] = i == len(mappings) - 1 and index >= 0x1000
936             i += 1
937         if result == None:
938             result = FindSubentryInfos(index, subIndex, MappingDictionary)
939             if result:
940                 result["user_defined"] = False
941         return result
942     
943     def GetTypeIndex(self, typename):
944         result = None
945         mappings = self.GetMappings()
946         i = 0
947         while not result and i < len(mappings):
948             result = FindTypeIndex(typename, mappings[i])
949             i += 1
950         if result == None:
951             result = FindTypeIndex(typename, MappingDictionary)
952         return result
953     
954     def GetTypeName(self, typeindex):
955         result = None
956         mappings = self.GetMappings()
957         i = 0
958         while not result and i < len(mappings):
959             result = FindTypeName(typeindex, mappings[i])
960             i += 1
961         if result == None:
962             result = FindTypeName(typeindex, MappingDictionary)
963         return result
964     
965     def GetTypeDefaultValue(self, typeindex):
966         result = None
967         mappings = self.GetMappings()
968         i = 0
969         while not result and i < len(mappings):
970             result = FindTypeDefaultValue(typeindex, mappings[i])
971             i += 1
972         if result == None:
973             result = FindTypeDefaultValue(typeindex, MappingDictionary)
974         return result
975     
976     def GetMapVariableList(self):
977         list = FindMapVariableList(MappingDictionary, self)
978         for mapping in self.GetMappings():
979             list.extend(FindMapVariableList(mapping, self))
980         list.sort()
981         return list
982     
983     def GetMandatoryIndexes(self, node = None):
984         list = FindMandatoryIndexes(MappingDictionary)
985         for mapping in self.GetMappings():
986             list.extend(FindMandatoryIndexes(mapping))
987         return list
988     
989     def GetCustomisableTypes(self):
990         dic = {}
991         for index, valuetype in CustomisableTypes:
992             name = self.GetTypeName(index)
993             dic[index] = [name, valuetype]
994         return dic
995
996 #-------------------------------------------------------------------------------
997 #                            Type helper functions
998 #-------------------------------------------------------------------------------
999
1000     def IsStringType(self, index):
1001         if index in (0x9, 0xA, 0xB):
1002             return True
1003         elif 0xA0 <= index < 0x100:
1004             result = self.GetEntry(index, 1)
1005             if result is not None and result in (0x9, 0xA, 0xB):
1006                 return True
1007         return False
1008
1009 #-------------------------------------------------------------------------------
1010 #                            Type and Map Variable Lists
1011 #-------------------------------------------------------------------------------
1012     
1013     def GetTypeList(self):
1014         list = FindTypeList(MappingDictionary)
1015         for mapping in self.GetMappings():
1016             list.extend(FindTypeList(mapping))
1017         list.sort()
1018         return ",".join(list)
1019
1020     """
1021     Generate the list of variables that can be mapped for the current node
1022     """
1023     def GenerateMapList(self):
1024         self.MapList = "None"
1025         self.NameTranslation = {"None" : "00000000"}
1026         self.MapTranslation = {"00000000" : "None"}
1027         list = self.GetMapVariableList()
1028         for index, subIndex, size, name in list:
1029             self.MapList += ",%s"%name
1030             map = "%04X%02X%02X"%(index,subIndex,size)
1031             self.NameTranslation[name] = map
1032             self.MapTranslation[map] = name
1033
1034     def GetMapValue(self, mapname):
1035         if mapname == "None":
1036             return 0
1037         else:
1038             list = self.GetMapVariableList()
1039             for index, subIndex, size, name in list:
1040                 if mapname == name:
1041                     return (index << 16) + (subIndex << 8) + size
1042             return None
1043     
1044     def GetMapName(self, value):
1045         if value != 0:
1046             index = value >> 16
1047             subindex = (value >> 8) % (1 << 8)
1048             result = self.GetSubentryInfos(index, subindex)
1049             if result:
1050                 return result["name"]
1051         return "None"
1052     
1053     """
1054     Return the list of variables that can be mapped for the current node
1055     """
1056     def GetMapList(self):
1057         list = ["None"] + [name for index, subIndex, size, name in self.GetMapVariableList()]
1058         return ",".join(list)
1059
1060 def BE_to_LE(value):
1061     """
1062     Convert Big Endian to Little Endian 
1063     @param value: value expressed in Big Endian
1064     @param size: number of bytes generated
1065     @return: a string containing the value converted
1066     """
1067     
1068     data = [char for char in value]
1069     data.reverse()
1070     return int("".join(["%2.2X"%ord(char) for char in data]), 16)
1071
1072 def LE_to_BE(value, size):
1073     """
1074     Convert Little Endian to Big Endian
1075     @param value: value expressed in integer
1076     @param size: number of bytes generated
1077     @return: a string containing the value converted
1078     """
1079     
1080     data = ("%" + str(size * 2) + "." + str(size * 2) + "X") % value
1081     list_car = [data[i:i+2] for i in xrange(0, len(data), 2)]
1082     list_car.reverse()
1083     return "".join([chr(int(car, 16)) for car in list_car])
1084