]> rtime.felk.cvut.cz Git - CanFestival-3.git/blobdiff - objdictgen/nodemanager.py
Remove deletion PDO when mapping undefined in export to EDS
[CanFestival-3.git] / objdictgen / nodemanager.py
index 16148048371d387adaa8b0e5ef45c74b848d9909..bbac2b1696c5aecb4c02ad925be8461addc76573 100755 (executable)
@@ -150,13 +150,12 @@ class NodeManager:
     """
     Constructor
     """
-    def __init__(self, cwd):
+    def __init__(self):
         self.LastNewIndex = 0
         self.FilePaths = {}
         self.FileNames = {}
         self.NodeIndex = None
         self.CurrentNode = None
-        self.ScriptDirectory = cwd
         self.UndoBuffers = {}
 
 #-------------------------------------------------------------------------------
@@ -201,13 +200,14 @@ class NodeManager:
             self.CurrentNode.SetNodeType(type)
             self.CurrentNode.SetNodeDescription(description)
             AddIndexList = self.GetMandatoryIndexes()
+            AddSubIndexList = []
             if NMT == "NodeGuarding":
                 AddIndexList.extend([0x100C, 0x100D])
             elif NMT == "Heartbeat":
                 AddIndexList.append(0x1017)
             for option in options:
                 if option == "DS302":
-                    DS302Path = os.path.join(self.ScriptDirectory, "config/DS-302.prf")
+                    DS302Path = os.path.join(os.path.split(__file__)[0], "config/DS-302.prf")
                     # Charging DS-302 profile if choosen by user
                     if os.path.isfile(DS302Path):
                         try:
@@ -226,11 +226,24 @@ class NodeManager:
                     AddIndexList.extend([0x1010, 0x1011, 0x1020])
                 elif option == "StoreEDS":
                     AddIndexList.extend([0x1021, 0x1022])
+            if type == "slave":
+                # add default SDO server
+                AddIndexList.append(0x1200)
+                # add default 4 receive and 4 transmit PDO
+                for comm, mapping in [(0x1400, 0x1600),(0x1800, 0x1A00)]:
+                    firstparamindex = self.GetLineFromIndex(comm)
+                    firstmappingindex = self.GetLineFromIndex(mapping)
+                    AddIndexList.extend(range(firstparamindex, firstparamindex + 4))
+                    for idx in range(firstmappingindex, firstmappingindex + 4):
+                        AddIndexList.append(idx)
+                        AddSubIndexList.append((idx, 8))
             # Add a new buffer 
-            index = self.AddNodeBuffer()
+            index = self.AddNodeBuffer(self.CurrentNode.Copy(), False)
             self.SetCurrentFilePath("")
             # Add Mandatory indexes
             self.ManageEntriesOfCurrent(AddIndexList, [])
+            for idx, num in AddSubIndexList:
+                self.AddSubentriesToCurrent(idx, num)
             return index
         else:
             return result
@@ -248,7 +261,7 @@ class NodeManager:
                 node.SetSpecificMenu(AddMenuEntries)
                 return None
             except:
-                return "Syntax Error\nBad OD Profile file!."
+                return "Syntax Error\nBad OD Profile file!"
         else:
             # Default profile
             node.SetProfileName("None")
@@ -260,15 +273,19 @@ class NodeManager:
     Open a file and store it in a new buffer
     """
     def OpenFileInCurrent(self, filepath):
-        # Open and load file
-        file = open(filepath, "r")
-        node = load(file)
-        file.close()
-        self.CurrentNode = node
-        # Add a new buffer and defining current state
-        index = self.AddNodeBuffer(self.CurrentNode.Copy(), True)
-        self.SetCurrentFilePath(filepath)
-        return index
+        try:
+            # Open and load file
+            file = open(filepath, "r")
+            node = load(file)
+            file.close()
+            self.CurrentNode = node
+            self.CurrentNode.SetNodeID(0)
+            # Add a new buffer and defining current state
+            index = self.AddNodeBuffer(self.CurrentNode.Copy(), True)
+            self.SetCurrentFilePath(filepath)
+            return index
+        except:
+            return "Unable to load file \"%s\"!"%filepath
 
     """
     Save current node in  a file
@@ -293,8 +310,21 @@ class NodeManager:
     """
     def CloseCurrent(self, ignore = False):
         # Verify if it's not forced that the current node is saved before closing it
-        if self.UndoBuffers[self.NodeIndex].IsCurrentSaved() or ignore:
+        if self.NodeIndex in self.UndoBuffers and (self.UndoBuffers[self.NodeIndex].IsCurrentSaved() or ignore):
             self.RemoveNodeBuffer(self.NodeIndex)
+            if len(self.UndoBuffers) > 0:
+                previousindexes = [idx for idx in self.UndoBuffers.keys() if idx < self.NodeIndex]
+                nextindexes = [idx for idx in self.UndoBuffers.keys() if idx > self.NodeIndex]
+                if len(previousindexes) > 0:
+                    previousindexes.sort()
+                    self.NodeIndex = previousindexes[-1]
+                elif len(nextindexes) > 0:
+                    nextindexes.sort()
+                    self.NodeIndex = nextindexes[0]
+                else:
+                    self.NodeIndex = None
+            else:
+                self.NodeIndex = None
             return True
         return False
 
@@ -303,12 +333,11 @@ class NodeManager:
     """
     def ImportCurrentFromEDSFile(self, filepath):
         # Generate node from definition in a xml file
-        result = eds_utils.GenerateNode(filepath, self.ScriptDirectory)
+        result = eds_utils.GenerateNode(filepath)
         if isinstance(result, Node):
             self.CurrentNode = result
-            index = self.AddNodeBuffer()
+            index = self.AddNodeBuffer(self.CurrentNode.Copy(), False)
             self.SetCurrentFilePath("")
-            self.BufferCurrentNode()
             return index
         else:
             return result
@@ -317,13 +346,14 @@ class NodeManager:
     Export to an eds file and store it in a new buffer if no node edited
     """
     def ExportCurrentToEDSFile(self, filepath):
-        return eds_utils.GenerateEDSFile(filepath, self)
+        return eds_utils.GenerateEDSFile(filepath, self.CurrentNode)
     
     """
     Build the C definition of Object Dictionary for current node 
     """
     def ExportCurrentToCFile(self, filepath):
-        return gen_cfile.GenerateFile(filepath, self)
+        if self.CurrentNode:
+            return gen_cfile.GenerateFile(filepath, self.CurrentNode)
 
 #-------------------------------------------------------------------------------
 #                        Add Entries to Current Functions
@@ -333,28 +363,36 @@ class NodeManager:
     Add the specified number of subentry for the given entry. Verify that total
     number of subentry (except 0) doesn't exceed nbmax defined
     """
-    def AddSubentriesToCurrent(self, index, number):
+    def AddSubentriesToCurrent(self, index, number, node = None):
+        disable_buffer = node != None
+        if node == None:
+            node = self.CurrentNode
         # Informations about entry
-        length = self.CurrentNode.GetEntry(index, 0)
-        infos = self.GetEntryInfos(index)
-        subentry_infos = self.GetSubentryInfos(index, 1)
+        length = node.GetEntry(index, 0)
+        infos = node.GetEntryInfos(index)
+        subentry_infos = node.GetSubentryInfos(index, 1)
         # Get default value for subindex
         if "default" in subentry_infos:
             default = subentry_infos["default"]
         else:
             default = self.GetTypeDefaultValue(subentry_infos["type"])   
         # First case entry is record
-        if infos["struct"] & OD_IdenticalSubindexes:
+        if infos["struct"] & OD_IdenticalSubindexes: 
             for i in xrange(1, min(number,subentry_infos["nbmax"]-length) + 1):
-                self.CurrentNode.AddEntry(index, length + i, default)
-            self.BufferCurrentNode()
+                node.AddEntry(index, length + i, default)
+            if not disable_buffer:
+                self.BufferCurrentNode()
+            return None
         # Second case entry is array, only possible for manufacturer specific
         elif infos["struct"] & OD_MultipleSubindexes and 0x2000 <= index <= 0x5FFF:
             values = {"name" : "Undefined", "type" : 5, "access" : "rw", "pdo" : True}
             for i in xrange(1, min(number,0xFE-length) + 1):
-                self.CurrentNode.AddMappingEntry(index, length + i, values = values.copy())
-                self.CurrentNode.AddEntry(index, length + i, 0)
-            self.BufferCurrentNode()
+                node.AddMappingEntry(index, length + i, values = values.copy())
+                node.AddEntry(index, length + i, 0)
+            if not disable_buffer:
+                self.BufferCurrentNode()
+            return None
+            
 
     """
     Remove the specified number of subentry for the given entry. Verify that total
@@ -364,9 +402,13 @@ class NodeManager:
         # Informations about entry
         infos = self.GetEntryInfos(index)
         length = self.CurrentNode.GetEntry(index, 0)
+        if "nbmin" in infos:
+            nbmin = infos["nbmin"]
+        else:
+            nbmin = 1
         # Entry is a record, or is an array of manufacturer specific
         if infos["struct"] & OD_IdenticalSubindexes or 0x2000 <= index <= 0x5FFF and infos["struct"] & OD_IdenticalSubindexes:
-            for i in xrange(min(number, length - 1)):
+            for i in xrange(min(number, length - nbmin)):
                 self.RemoveCurrentVariable(index, length - i)
             self.BufferCurrentNode()
 
@@ -438,7 +480,10 @@ class NodeManager:
     """
     Add entries specified in addinglist and remove entries specified in removinglist
     """
-    def ManageEntriesOfCurrent(self, addinglist, removinglist):
+    def ManageEntriesOfCurrent(self, addinglist, removinglist, node = None):
+        disable_buffer = node != None
+        if node == None:
+            node = self.CurrentNode
         # Add all the entries in addinglist
         for index in addinglist:
             infos = self.GetEntryInfos(index)
@@ -450,7 +495,12 @@ class NodeManager:
                         default = subentry_infos["default"]
                     else:
                         default = self.GetTypeDefaultValue(subentry_infos["type"])
-                    self.CurrentNode.AddEntry(index, 1, default)
+                    node.AddEntry(index, value = [])
+                    if "nbmin" in subentry_infos:
+                        for i in xrange(subentry_infos["nbmin"]):
+                            node.AddEntry(index, i + 1, default)
+                    else:
+                        node.AddEntry(index, 1, default)
                 # Second case entry is a record
                 else:
                     i = 1
@@ -460,7 +510,7 @@ class NodeManager:
                             default = subentry_infos["default"]
                         else:
                             default = self.GetTypeDefaultValue(subentry_infos["type"])
-                        self.CurrentNode.AddEntry(index, i, default)
+                        node.AddEntry(index, i, default)
                         i += 1
                         subentry_infos = self.GetSubentryInfos(index, i)
             # Third case entry is a record
@@ -470,13 +520,32 @@ class NodeManager:
                     default = subentry_infos["default"]
                 else:
                     default = self.GetTypeDefaultValue(subentry_infos["type"])
-                self.CurrentNode.AddEntry(index, 0, default)
+                node.AddEntry(index, 0, default)
         # Remove all the entries in removinglist
         for index in removinglist:
             self.RemoveCurrentVariable(index)
-        self.BufferCurrentNode()
+        if not disable_buffer:
+            self.BufferCurrentNode()
+        return None
 
 
+    """
+    Reset an subentry from current node to its default value
+    """
+    def SetCurrentEntryToDefault(self, index, subindex, node = None):
+        disable_buffer = node != None
+        if node == None:
+            node = self.CurrentNode
+        if node.IsEntry(index, subindex):
+            subentry_infos = self.GetSubentryInfos(index, subindex)
+            if "default" in subentry_infos:
+                default = subentry_infos["default"]
+            else:
+                default = self.GetTypeDefaultValue(subentry_infos["type"])
+            node.SetEntry(index, subindex, default)
+            if not disable_buffer:
+                self.BufferCurrentNode()
+
     """
     Remove an entry from current node. Analize the index to perform the correct
     method
@@ -527,28 +596,32 @@ class NodeManager:
             if index in Mappings[-1]:
                 self.CurrentNode.RemoveMappingEntry(index, subIndex)
 
-    def AddMapVariableToCurrent(self, index, name, struct, number):
+    def AddMapVariableToCurrent(self, index, name, struct, number, node = None):
         if 0x2000 <= index <= 0x5FFF:
-            if not self.CurrentNode.IsEntry(index):
-                self.CurrentNode.AddMappingEntry(index, name = name, struct = struct)
+            disable_buffer = node != None
+            if node == None:
+                node = self.CurrentNode
+            if not node.IsEntry(index):
+                node.AddMappingEntry(index, name = name, struct = struct)
                 if struct == var:
                     values = {"name" : name, "type" : 0x05, "access" : "rw", "pdo" : True}
-                    self.CurrentNode.AddMappingEntry(index, 0, values = values)
-                    self.CurrentNode.AddEntry(index, 0, 0)
+                    node.AddMappingEntry(index, 0, values = values)
+                    node.AddEntry(index, 0, 0)
                 else:
                     values = {"name" : "Number of Entries", "type" : 0x05, "access" : "ro", "pdo" : False}
-                    self.CurrentNode.AddMappingEntry(index, 0, values = values)
+                    node.AddMappingEntry(index, 0, values = values)
                     if struct == rec:
                         values = {"name" : name + " %d[(sub)]", "type" : 0x05, "access" : "rw", "pdo" : True, "nbmax" : 0xFE}
-                        self.CurrentNode.AddMappingEntry(index, 1, values = values)
+                        node.AddMappingEntry(index, 1, values = values)
                         for i in xrange(number):
-                            self.CurrentNode.AddEntry(index, i + 1, 0)
+                            node.AddEntry(index, i + 1, 0)
                     else:
                         for i in xrange(number):
                             values = {"name" : "Undefined", "type" : 0x05, "access" : "rw", "pdo" : True}
-                            self.CurrentNode.AddMappingEntry(index, i + 1, values = values)
-                            self.CurrentNode.AddEntry(index, i + 1, 0)
-                self.BufferCurrentNode()
+                            node.AddMappingEntry(index, i + 1, values = values)
+                            node.AddEntry(index, i + 1, 0)
+                if not disable_buffer:
+                    self.BufferCurrentNode()
                 return None
             else:
                 return "Index 0x%04X already defined!"%index
@@ -596,32 +669,29 @@ class NodeManager:
                 self.CurrentNode.SetParamsEntry(index, None, callback = value)
                 self.BufferCurrentNode()
 
-    def ResetCurrentDefaultValue(self, index, subIndex):
-        subentry_infos = self.GetSubentryInfos(index, subIndex)
-        if "default" in subentry_infos:
-            default = subentry_infos["default"]
-        else:
-            default = self.GetTypeDefaultValue(subentry_infos["type"])
-        self.CurrentNode.SetEntry(index, subIndex, default)
-        
-
-    def SetCurrentEntry(self, index, subIndex, value, name, editor):
-        if self.CurrentNode and self.CurrentNode.IsEntry(index):
+    def SetCurrentEntry(self, index, subIndex, value, name, editor, node = None):
+        disable_buffer = node != None
+        if node == None:
+            node = self.CurrentNode
+        if node and node.IsEntry(index):
             if name == "value":
-                if editor == None:
-                    self.CurrentNode.SetEntry(index, subIndex, value)
-                elif editor == "map":
-                    value = self.CurrentNode.GetMapValue(value)
-                    if value:
-                        self.CurrentNode.SetEntry(index, subIndex, value)
+                if editor == "map":
+                    value = node.GetMapValue(value)
+                    if value is not None:
+                        node.SetEntry(index, subIndex, value)
                 elif editor == "bool":
                     value = value == "True"
-                    self.CurrentNode.SetEntry(index, subIndex, value)
+                    node.SetEntry(index, subIndex, value)
                 elif editor == "time":
-                    self.CurrentNode.SetEntry(index, subIndex, value)
+                    node.SetEntry(index, subIndex, value)
                 elif editor == "number":
                     try:
-                        self.CurrentNode.SetEntry(index, subIndex, int(value))
+                        node.SetEntry(index, subIndex, int(value))
+                    except:
+                        pass
+                elif editor == "float":
+                    try:
+                        node.SetEntry(index, subIndex, float(value))
                     except:
                         pass
                 elif editor == "domain":
@@ -629,9 +699,11 @@ class NodeManager:
                         if len(value) % 2 != 0:
                             value = "0" + value
                         value = value.decode('hex_codec')
-                        self.CurrentNode.SetEntry(index, subIndex, value)
+                        node.SetEntry(index, subIndex, value)
                     except:
                         pass
+                elif editor == "dcf":
+                    node.SetEntry(index, subIndex, value)
                 else:
                     subentry_infos = self.GetSubentryInfos(index, subIndex)
                     type = subentry_infos["type"]
@@ -639,42 +711,46 @@ class NodeManager:
                     for typeindex, typevalue in CustomisableTypes:
                         dic[typeindex] = typevalue
                     if type not in dic:
-                        type = self.CurrentNode.GetEntry(type)[1]
+                        type = node.GetEntry(type)[1]
                     if dic[type] == 0:
                         try:
-                            if value.startswith("0x"):
+                            if value.startswith("$NODEID"):
+                                value = "\"%s\""%value
+                            elif value.startswith("0x"):
                                 value = int(value, 16)
                             else:
                                 value = int(value)
-                            self.CurrentNode.SetEntry(index, subIndex, value)
+                            node.SetEntry(index, subIndex, value)
                         except:
                             pass
                     else:
-                        self.CurrentNode.SetEntry(index, subIndex, value)
+                        node.SetEntry(index, subIndex, value)
             elif name in ["comment", "save"]:
                 if editor == "option":
                     value = value == "Yes"
                 if name == "save":
-                    self.CurrentNode.SetParamsEntry(index, subIndex, save = value)
+                    node.SetParamsEntry(index, subIndex, save = value)
                 elif name == "comment":
-                    self.CurrentNode.SetParamsEntry(index, subIndex, comment = value)
+                    node.SetParamsEntry(index, subIndex, comment = value)
             else:
                 if editor == "type":
                     value = self.GetTypeIndex(value)
                     size = self.GetEntryInfos(value)["size"]
-                    self.CurrentNode.UpdateMapVariable(index, subIndex, size)
+                    node.UpdateMapVariable(index, subIndex, size)
                 elif editor in ["access","raccess"]:
                     dic = {}
                     for abbrev,access in AccessType.iteritems():
                         dic[access] = abbrev
                     value = dic[value]
-                    if editor == "raccess" and not self.CurrentNode.IsMappingEntry(index):
+                    if editor == "raccess" and not node.IsMappingEntry(index):
                         entry_infos = self.GetEntryInfos(index)
-                        self.CurrentNode.AddMappingEntry(index, name = entry_infos["name"], struct = 7)
-                        self.CurrentNode.AddMappingEntry(index, 0, values = self.GetSubentryInfos(index, 0, False).copy())
-                        self.CurrentNode.AddMappingEntry(index, 1, values = self.GetSubentryInfos(index, 1, False).copy())
-                self.CurrentNode.SetMappingEntry(index, subIndex, values = {name : value})
-            self.BufferCurrentNode()
+                        node.AddMappingEntry(index, name = entry_infos["name"], struct = 7)
+                        node.AddMappingEntry(index, 0, values = self.GetSubentryInfos(index, 0, False).copy())
+                        node.AddMappingEntry(index, 1, values = self.GetSubentryInfos(index, 1, False).copy())
+                node.SetMappingEntry(index, subIndex, values = {name : value})
+            if not disable_buffer:
+                self.BufferCurrentNode()
+            return None
 
     def SetCurrentEntryName(self, index, name):
         self.CurrentNode.SetMappingEntry(index, name=name)
@@ -727,6 +803,9 @@ class NodeManager:
     def GetBufferNumber(self):
         return len(self.UndoBuffers)
 
+    def GetBufferIndexes(self):
+        return self.UndoBuffers.keys()
+
     def LoadCurrentPrevious(self):
         self.CurrentNode = self.UndoBuffers[self.NodeIndex].Previous().Copy()
     
@@ -753,11 +832,6 @@ class NodeManager:
     def GetCurrentNodeIndex(self):
         return self.NodeIndex
     
-    def GetCurrentNode(self):
-        if self.NodeIndex:
-            return self.CurrentNode
-        return None
-    
     def GetCurrentFilename(self):
         return self.GetFilename(self.NodeIndex)
     
@@ -852,7 +926,13 @@ class NodeManager:
         else:
             return ""
 
-    def GetCurrentNodeID(self):
+    def GetCurrentNodeCopy(self):
+        if self.CurrentNode:
+            return self.CurrentNode.Copy()
+        else:
+            return None
+    
+    def GetCurrentNodeID(self, node = None):
         if self.CurrentNode:
             return self.CurrentNode.GetNodeID()
         else:
@@ -864,7 +944,7 @@ class NodeManager:
         type = self.CurrentNode.GetNodeType()
         description = self.CurrentNode.GetNodeDescription()
         return name, id, type, description
-        
+    
     def SetCurrentNodeInfos(self, name, id, type, description):
         self.CurrentNode.SetNodeName(name)
         self.CurrentNode.SetNodeID(id)
@@ -872,6 +952,18 @@ class NodeManager:
         self.CurrentNode.SetNodeDescription(description)
         self.BufferCurrentNode()
 
+    def GetCurrentNodeDefaultStringSize(self):
+        if self.CurrentNode:
+            return self.CurrentNode.GetDefaultStringSize()
+        else:
+            return Node.DefaultStringSize
+    
+    def SetCurrentNodeDefaultStringSize(self, size):
+        if self.CurrentNode:
+            self.CurrentNode.SetDefaultStringSize(size)
+        else:
+            Node.DefaultStringSize = size
+
     def GetCurrentProfileName(self):
         if self.CurrentNode:
             return self.CurrentNode.GetProfileName()
@@ -882,9 +974,9 @@ class NodeManager:
             return self.CurrentNode.IsEntry(index)
         return False
     
-    def GetCurrentEntry(self, index, subIndex = None):
+    def GetCurrentEntry(self, index, subIndex = None, compute = True):
         if self.CurrentNode:
-            return self.CurrentNode.GetEntry(index, subIndex)
+            return self.CurrentNode.GetEntry(index, subIndex, compute)
         return None
     
     def GetCurrentParamsEntry(self, index, subIndex = None):
@@ -920,10 +1012,7 @@ class NodeManager:
         return validchoices
     
     def HasCurrentEntryCallbacks(self, index):
-        if self.CurrentNode and self.CurrentNode.IsEntry(index):
-            entry_infos = self.GetEntryInfos(index)
-            if "callback" in entry_infos:
-                return entry_infos["callback"]
+        if self.CurrentNode:
             return self.CurrentNode.HasEntryCallbacks(index)
         return False
     
@@ -936,9 +1025,9 @@ class NodeManager:
             entry_infos = node.GetEntryInfos(index)
             data = []
             editors = []
-            values = node.GetEntry(index)
+            values = node.GetEntry(index, compute = False)
             params = node.GetParamsEntry(index)
-            if type(values) == ListType:
+            if isinstance(values, ListType):
                 for i, value in enumerate(values):
                     data.append({"value" : value})
                     data[-1].update(params[i])      
@@ -953,7 +1042,7 @@ class NodeManager:
                 dic["access"] = AccessType[infos["access"]]
                 dic["save"] = OptionType[dic["save"]]
                 editor = {"subindex" : None, "save" : "option", "callback" : "option", "comment" : "string"}
-                if type(values) == ListType and i == 0:
+                if isinstance(values, ListType) and i == 0:
                     editor["name"] = None
                     editor["type"] = None
                     if 0x1600 <= index <= 0x17FF or 0x1A00 <= index <= 0x1C00:
@@ -990,12 +1079,15 @@ class NodeManager:
                         editor["value"] = "map"
                         dic["value"] = node.GetMapName(dic["value"])
                     else:
-                        if dic["type"].startswith("VISIBLE_STRING"):
+                        if dic["type"].startswith("VISIBLE_STRING") or dic["type"].startswith("OCTET_STRING"):
                             editor["value"] = "string"
                         elif dic["type"] in ["TIME_OF_DAY","TIME_DIFFERENCE"]:
                             editor["value"] = "time"
                         elif dic["type"] == "DOMAIN":
-                            editor["value"] = "domain"
+                            if index == 0x1F22:
+                                editor["value"] = "dcf"
+                            else:
+                                editor["value"] = "domain"
                             dic["value"] = dic["value"].encode('hex_codec')
                         elif dic["type"] == "BOOLEAN":
                             editor["value"] = "bool"
@@ -1004,14 +1096,17 @@ class NodeManager:
                         if result:
                             values = result.groups()
                             if values[0] == "UNSIGNED":
-                                format = "0x%0" + str(int(values[1])/4) + "X"
-                                dic["value"] = format%dic["value"]
+                                try:
+                                    format = "0x%0" + str(int(values[1])/4) + "X"
+                                    dic["value"] = format%dic["value"]
+                                except:
+                                    pass
                                 editor["value"] = "string"
                             if values[0] == "INTEGER":
                                 editor["value"] = "number"
                             elif values[0] == "REAL":
                                 editor["value"] = "float"
-                            elif values[0] == "VISIBLE_STRING":
+                            elif values[0] in ["VISIBLE_STRING", "OCTET_STRING"]:
                                 editor["length"] = values[0]
                         result = range_model.match(dic["type"])
                         if result:
@@ -1024,6 +1119,17 @@ class NodeManager:
         else:
             return None
 
+    def AddToDCF(self, node_id, index, subindex, size, value):
+        if self.CurrentNode.IsEntry(0x1F22, node_id):
+            dcf_value = self.CurrentNode.GetEntry(0x1F22, node_id)
+            if dcf_value != "":
+                nbparams = BE_to_LE(dcf_value[:4])
+            else:
+                nbparams = 0
+            new_value = LE_to_BE(nbparams + 1, 4) + dcf_value[4:]
+            new_value += LE_to_BE(index, 2) + LE_to_BE(subindex, 1) + LE_to_BE(size, 4) + LE_to_BE(value, size)
+            self.CurrentNode.SetEntry(0x1F22, node_id, new_value)
+
 #-------------------------------------------------------------------------------
 #                         Node Informations Functions
 #-------------------------------------------------------------------------------
@@ -1081,7 +1187,7 @@ class NodeManager:
         else:
             return []
 
-    def GetMandatoryIndexes(self, node = None):
+    def GetMandatoryIndexes(self):
         if self.CurrentNode:
             return self.CurrentNode.GetMandatoryIndexes()
         else: