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