Subversion Repositories HomeAutomation

Rev

Rev 749 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 749 Rev 750
1
###########################################################
1
###########################################################
2
#
2
#
3
# Daemon configuration
3
# Daemon configuration
4
#
4
#
5
###########################################################
5
###########################################################
6
import logging as log
6
import logging as log
7
import pickle
7
import pickle
8
import hashlib
8
import hashlib
9
import os
9
import os
10
import imp
10
import imp
11
import re
11
import re
12
from ConfigParser import ConfigParser
12
from ConfigParser import ConfigParser
13
import filters
13
import filters
14
import statespaces
14
import statespaces
15
from CanPktHandlerBase import CanPktHandlerBase
15
from CanPktHandlerBase import CanPktHandlerBase
16
from CanPktHandler1 import CanPktHandler1
16
from CanPktHandler1 import CanPktHandler1
-
 
17
 
-
 
18
from NodeIfSerial import NodeIfSerial
-
 
19
from NodeIfTCP import NodeIfTCP
-
 
20
from NodeIfUDP import NodeIfUDP
-
 
21
from NodeIfTCPTLS import NodeIfTCPTLS
-
 
22
from NodeIfCanStim import NodeIfCanStim
17
 
23
 
18
class DynamicModuleCfg:
24
class DynamicModuleCfg:
19
    """Dynamic module manager"""
25
    """Dynamic module manager"""
20
 
26
 
21
    modSubDir = None
27
    modSubDir = None
22
    CHECKSUM_FILE = 'checksums'
28
    CHECKSUM_FILE = 'checksums'
23
    CHECKSUM_SECTION = 'SHA-1_CHECKSUMS'
29
    CHECKSUM_SECTION = 'SHA-1_CHECKSUMS'
24
   
30
   
25
    def __init__(self, modSubDir):
31
    def __init__(self, modSubDir):
26
        self.modSubDir = modSubDir
32
        self.modSubDir = modSubDir
27
        self.checkSumFile = modSubDir + '/' + self.CHECKSUM_FILE
33
        self.checkSumFile = modSubDir + '/' + self.CHECKSUM_FILE
28
        if not os.path.exists(self.checkSumFile):
34
        if not os.path.exists(self.checkSumFile):
29
            self.__createCsumsFile()
35
            self.__createCsumsFile()
30
   
36
   
31
    def loadModule(self, className):
37
    def loadModule(self, className):
32
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
38
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
33
        log.debug('Reading from ' + pFileName)
39
        log.debug('Reading from ' + pFileName)
34
        fp = open(pFileName, 'r')
40
        fp = open(pFileName, 'r')
35
        p = pickle.Unpickler(fp)
41
        p = pickle.Unpickler(fp)
36
        loadedMod = p.load()
42
        loadedMod = p.load()
37
        fp.close()
43
        fp.close()
38
        if not self.__verifyCheckSum(className, pFileName):
44
        if not self.__verifyCheckSum(className, pFileName):
39
            print 'Invalid checksum'
45
            print 'Invalid checksum'
40
            return None
46
            return None
41
        else:
47
        else:
42
            return loadedMod
48
            return loadedMod
43
       
49
       
44
       
50
       
45
    def loadModules(self, config = None):
51
    def loadModules(self, config = None):
46
        subDirFiles = os.listdir(os.getcwd() + '/' + self.modSubDir)
52
        subDirFiles = os.listdir(os.getcwd() + '/' + self.modSubDir)
47
        p = re.compile('.p$', re.IGNORECASE)
53
        p = re.compile('.p$', re.IGNORECASE)
48
        modFiles = [elem for elem in subDirFiles if p.search(elem) is not None]
54
        modFiles = [elem for elem in subDirFiles if p.search(elem) is not None]
49
        modNames = []
55
        modNames = []
50
        for mfName in modFiles:
56
        for mfName in modFiles:
51
            modNames.append(mfName.split('.')[0])
57
            modNames.append(mfName.split('.')[0])
52
        log.debug('Found modules: ' + str(modNames))
58
        log.debug('Found modules: ' + str(modNames))
53
        myMods = {}
59
        myMods = {}
54
        for mName in modNames:
60
        for mName in modNames:
55
            classObj = self.loadModule(mName)
61
            classObj = self.loadModule(mName)
56
            if classObj is not None:
62
            if classObj is not None:
57
                myMods[mName] = classObj
63
                myMods[mName] = classObj
58
        return myMods
64
        return myMods
59
 
65
 
60
   
66
   
61
    def saveModule(self, className, classObj):
67
    def saveModule(self, className, classObj):
62
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
68
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
63
        log.debug('Writing to ' + pFileName)
69
        log.debug('Writing to ' + pFileName)
64
        fp = open(pFileName, 'w')
70
        fp = open(pFileName, 'w')
65
        p = pickle.Pickler(fp)
71
        p = pickle.Pickler(fp)
66
        p.dump(classObj)
72
        p.dump(classObj)
67
        fp.close()
73
        fp.close()
68
        self.__writeCheckSum(className, pFileName)
74
        self.__writeCheckSum(className, pFileName)
69
   
75
   
70
   
76
   
71
    def __doCheckSum(self, filename):
77
    def __doCheckSum(self, filename):
72
        f = open(filename, 'r')
78
        f = open(filename, 'r')
73
        data = f.read()
79
        data = f.read()
74
        f.close()
80
        f.close()
75
        hasher = hashlib.sha1()
81
        hasher = hashlib.sha1()
76
        hasher.update(data)
82
        hasher.update(data)
77
        digest = hasher.hexdigest()
83
        digest = hasher.hexdigest()
78
        return digest
84
        return digest
79
   
85
   
80
   
86
   
81
    def __createCsumsFile(self):
87
    def __createCsumsFile(self):
82
         csumsfile = open(self.checkSumFile, 'w')
88
         csumsfile = open(self.checkSumFile, 'w')
83
         csumsfile.write('[' + self.CHECKSUM_SECTION + ']\n')
89
         csumsfile.write('[' + self.CHECKSUM_SECTION + ']\n')
84
         csumsfile.close()
90
         csumsfile.close()
85
   
91
   
86
   
92
   
87
    def __writeCheckSum(self, entryname, filename):
93
    def __writeCheckSum(self, entryname, filename):
88
        csumsfile = open(self.checkSumFile, 'r+')
94
        csumsfile = open(self.checkSumFile, 'r+')
89
        csumcfg = ConfigParser()
95
        csumcfg = ConfigParser()
90
        csumcfg.readfp(csumsfile)
96
        csumcfg.readfp(csumsfile)
91
        digest = self.__doCheckSum(filename)
97
        digest = self.__doCheckSum(filename)
92
        csumcfg.set(self.CHECKSUM_SECTION, entryname, digest)
98
        csumcfg.set(self.CHECKSUM_SECTION, entryname, digest)
93
        csumsfile.seek(0)
99
        csumsfile.seek(0)
94
        csumcfg.write(csumsfile)
100
        csumcfg.write(csumsfile)
95
       
101
       
96
       
102
       
97
    def __verifyCheckSum(self, entryname, filename):
103
    def __verifyCheckSum(self, entryname, filename):
98
        csumsfile = open(self.checkSumFile, 'r')
104
        csumsfile = open(self.checkSumFile, 'r')
99
        csumcfg = ConfigParser()
105
        csumcfg = ConfigParser()
100
        csumcfg.readfp(csumsfile)
106
        csumcfg.readfp(csumsfile)
101
        digest = csumcfg.get(self.CHECKSUM_SECTION, entryname)
107
        digest = csumcfg.get(self.CHECKSUM_SECTION, entryname)
102
        cur_digest = self.__doCheckSum(filename)
108
        cur_digest = self.__doCheckSum(filename)
103
        log.debug('Old checksum ' + digest + '\nNew checksum: ' + cur_digest)
109
        log.debug('Old checksum ' + digest + '\nNew checksum: ' + cur_digest)
104
        if cur_digest == digest:
110
        if cur_digest == digest:
105
            return True
111
            return True
106
        return False
112
        return False
107
   
113
   
108
   
114
   
109
    def importModule(self, className, requiredAttributes):
115
    def importModule(self, className, requiredAttributes):
110
        """Imports a given class from the module with the same name """
116
        """Imports a given class from the module with the same name """
111
 
117
 
112
        codeFile = os.getcwd() + '/' + self.modSubDir + '/' + className + '.py'
118
        codeFile = os.getcwd() + '/' + self.modSubDir + '/' + className + '.py'
113
        mod = imp.load_source(self.modSubDir + '.' + className, codeFile)
119
        mod = imp.load_source(self.modSubDir + '.' + className, codeFile)
114
        newClass = eval('mod.' + className)()
120
        newClass = eval('mod.' + className)()
115
       
121
       
116
        for ra in requiredAttributes:
122
        for ra in requiredAttributes:
117
            if not hasattr(newClass, ra):
123
            if not hasattr(newClass, ra):
118
                print className, ': missing required symbol \"' + ra + '\"'
124
                print className, ': missing required symbol \"' + ra + '\"'
119
                return None
125
                return None
120
       
126
       
121
        self.saveModule(className, newClass)
127
        self.saveModule(className, newClass)
122
        return newClass
128
        return newClass
123
 
129
 
124
 
130
 
125
class FilterCfg:
131
class FilterCfg:
126
    """Filter resource manager"""
132
    """Filter resource manager"""
127
   
133
   
128
    REQUIRED_ATTRIBUTES = ['ASSOCIATED_SPACES', 'DESCRIPTIVE_NAME',
134
    REQUIRED_ATTRIBUTES = ['ASSOCIATED_SPACES', 'DESCRIPTIVE_NAME',
129
                           'attach', 'detach', 'filter']
135
                           'attach', 'detach', 'filter']
130
   
136
   
131
    dynamicModuleCfg = None
137
    dynamicModuleCfg = None
132
    FILTER_SUBDIR = 'filters'
138
    FILTER_SUBDIR = 'filters'
133
    filterModules = {}
139
    filterModules = {}
134
   
140
   
135
    def __init__(self):
141
    def __init__(self):
136
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
142
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
137
   
143
   
138
    def loadFilter(self, name):
144
    def loadFilter(self, name):
139
        newFilt = self.dynamicModuleCfg.loadModule(name)
145
        newFilt = self.dynamicModuleCfg.loadModule(name)
140
        if newFilt is not None:
146
        if newFilt is not None:
141
            self.filterModules[name] = newFilt
147
            self.filterModules[name] = newFilt
142
            return True
148
            return True
143
        else:
149
        else:
144
            return False
150
            return False
145
 
151
 
146
    def loadFilters(self, config = None):
152
    def loadFilters(self, config = None):
147
        self.filterModules = self.dynamicModuleCfg.loadModules()
153
        self.filterModules = self.dynamicModuleCfg.loadModules()
148
        for fM in self.filterModules:
154
        for fM in self.filterModules:
149
            log.debug(fM)
155
            log.debug(fM)
150
 
156
 
151
    def __saveFilter(self, className, classObj):
157
    def __saveFilter(self, className, classObj):
152
        self.dynamicModuleCfg.saveModule(className, classObj)
158
        self.dynamicModuleCfg.saveModule(className, classObj)
153
 
159
 
154
    def saveFilters(self):
160
    def saveFilters(self):
155
        for className in self.filterModules:
161
        for className in self.filterModules:
156
            self.__saveFilter(className, self.filterModules[className])
162
            self.__saveFilter(className, self.filterModules[className])
157
       
163
       
158
    def importFilter(self, className):
164
    def importFilter(self, className):
159
        """Imports a given filter definition """
165
        """Imports a given filter definition """
160
        classObj = self.dynamicModuleCfg.importModule(className, self.REQUIRED_ATTRIBUTES)
166
        classObj = self.dynamicModuleCfg.importModule(className, self.REQUIRED_ATTRIBUTES)
161
        if classObj is not None:
167
        if classObj is not None:
162
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
168
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
163
            return True
169
            return True
164
        else:
170
        else:
165
            return False
171
            return False
166
       
172
       
167
 
173
 
168
class StateSpaceCfg:
174
class StateSpaceCfg:
169
    """State space resource manager"""
175
    """State space resource manager"""
170
   
176
   
171
    REQUIRED_ATTRIBUTES = ['DESCRIPTIVE_NAME', 'RELATED_SPACES'
177
    REQUIRED_ATTRIBUTES = ['DESCRIPTIVE_NAME', 'RELATED_SPACES'
172
                           'load', 'reset', 'run', 'unload']
178
                           'load', 'reset', 'run', 'unload']
173
   
179
   
174
    dynamicModuleCfg = None
180
    dynamicModuleCfg = None
175
    FILTER_SUBDIR = 'statespaces'
181
    FILTER_SUBDIR = 'statespaces'
176
    spaceModules = {}
182
    spaceModules = {}
177
   
183
   
178
    def __init__(self):
184
    def __init__(self):
179
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
185
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
180
   
186
   
181
    def loadSpace(self, name):
187
    def loadSpace(self, name):
182
        newSpace = self.dynamicModuleCfg.loadModule(name)
188
        newSpace = self.dynamicModuleCfg.loadModule(name)
183
        if newSpace is not None:
189
        if newSpace is not None:
184
            self.spaceModules[name] = newFilt
190
            self.spaceModules[name] = newFilt
185
            return True
191
            return True
186
        else:
192
        else:
187
            return False
193
            return False
188
 
194
 
189
    def loadSpaces(self, config = None):
195
    def loadSpaces(self, config = None):
190
        self.spaceModules = self.dynamicModuleCfg.loadModules()
196
        self.spaceModules = self.dynamicModuleCfg.loadModules()
191
        for sM in self.spaceModules:
197
        for sM in self.spaceModules:
192
            log.debug(sM)
198
            log.debug(sM)
193
 
199
 
194
    def __saveSpace(self, className, classObj):
200
    def __saveSpace(self, className, classObj):
195
        self.dynamicModuleCfg.saveModule(className, classObj)
201
        self.dynamicModuleCfg.saveModule(className, classObj)
196
 
202
 
197
    def saveSpaces(self):
203
    def saveSpaces(self):
198
        for className in self.spaceModules:
204
        for className in self.spaceModules:
199
            self.__saveSpace(className, self.spaceModules[className])
205
            self.__saveSpace(className, self.spaceModules[className])
200
   
206
   
201
    def importSpace(self, name):
207
    def importSpace(self, name):
202
        """Imports a given state space definition file """
208
        """Imports a given state space definition file """
203
        classObj = self.dynamicModuleCfg.importModule(name, self.REQUIRED_ATTRIBUTES)
209
        classObj = self.dynamicModuleCfg.importModule(name, self.REQUIRED_ATTRIBUTES)
204
        if classObj is not None:
210
        if classObj is not None:
205
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
211
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
206
            return True
212
            return True
207
        else:
213
        else:
208
            return False
214
            return False
209
 
215
 
210
class DaemonConfig:
216
class DaemonConfig:
211
   
217
   
212
    stateSpaceCfg = None
218
    stateSpaceCfg = None
213
    filterCfg = None
219
    filterCfg = None
214
    pktHandler = None
220
    pktHandler = None
215
   
221
   
216
    filterChain = []
222
    filterChain = []
217
    nodeInterfaces = []
223
    nodeInterfaces = []
218
    nodeInterfaceMap = {}
224
    nodeInterfaceMap = {}
219
   
225
   
-
 
226
    INTERFACE_TYPES = {'serial' : NodeIfSerial, 'tcp' : NodeIfTCP,
-
 
227
                       'udp' : NodeIfUDP, 'sim' : NodeIfCanStim,
-
 
228
                       'tcptls' : NodeIfTCPTLS}
-
 
229
 
220
    def __init__ (self):
230
    def __init__ (self):
221
        self.filterCfg = FilterCfg()
231
        self.filterCfg = FilterCfg()
222
        self.stateSpaceCfg = StateSpaceCfg()
232
        self.stateSpaceCfg = StateSpaceCfg()
223
        self.pktHandler = CanPktHandler1()
233
        self.pktHandler = CanPktHandler1(self)
224
       
234
       
225
    def load(self):
235
    def load(self):
226
        self.stateSpaceCfg.loadSpaces()
236
        self.stateSpaceCfg.loadSpaces()
227
        self.stateSpaceCfg.loadFilters()
237
        self.filterCfg.loadFilters()
228
        __setupFilterBindings()
238
        self.__setupFilterBindings()
-
 
239
        self.__setupStateSpaceRelations()
229
        __setupFilterChain()
240
        self.__setupFilterChain()
230
   
241
 
231
    def save(self):
242
    def save(self):
232
        self.stateSpaceCfg.saveSpaces()
243
        self.stateSpaceCfg.saveSpaces()
233
        self.filterCfg.saveFilters()
244
        self.filterCfg.saveFilters()
-
 
245
       
-
 
246
    def addInterface(self, type, cfg = None):
-
 
247
        """ addInterface
-
 
248
        type - a valid interface type name
-
 
249
        cfg - interface configuration
-
 
250
        returns: True on success, False otherwise """
-
 
251
       
-
 
252
        if not self.INTERFACE_TYPES.has_key(type):
-
 
253
            log.debug('addInterface called with invalid interface type')
-
 
254
            return False
-
 
255
       
-
 
256
        cfg = self.INTERFACE_TYPES[type].DEFAULT_CONFIG
-
 
257
        print cfg
-
 
258
        nodeIf = self.INTERFACE_TYPES[type](self.pktHandler, cfg)
-
 
259
        print nodeIf
-
 
260
        self.nodeInterfaces.append(nodeIf)
-
 
261
   
-
 
262
    def remInterface(self, name):
-
 
263
        pass
234
       
264
       
235
    def __setupFilterChain(self):
265
    def __setupFilterChain(self):
236
        self.filterChain = ['DefaultFilter']
266
        self.filterChain = ['DefaultFilter']
237
   
267
   
238
    def __setupFilterBindings(self):
268
    def __setupFilterBindings(self):
239
        for f in self.filterCfg.filterModules.values():
269
        for f in self.filterCfg.filterModules.values():
240
            assocSpaces = []
270
            assocSpaces = []
241
            for s in f.ASSOCIATED_SPACES:
271
            for s in f.ASSOCIATED_SPACES:
242
                if self.stateSpaceCfg.spaceModules.has_key(s):
272
                if self.stateSpaceCfg.spaceModules.has_key(s):
243
                    assocSpaces.append(self.stateSpaceCfg.spaceModules[s])
273
                    assocSpaces.append(self.stateSpaceCfg.spaceModules[s])
244
                else:
274
                else:
245
                    print 'WARNING: Reference to undefined state space: ' + s
275
                    print 'WARNING: Reference to undefined state space: ' + s
246
            setattr(f, '__ASSOCIATED_SPACES__', assocSpaces)
276
            setattr(f, '__ASSOCIATED_SPACES__', assocSpaces)
247
   
277
 
248
 
-
 
249
    def setupStateSpaceRelations(self):
278
    def __setupStateSpaceRelations(self):
250
        for sm in self.stateSpaceCfg.spaceModules:
279
        for sm in self.stateSpaceCfg.spaceModules:
251
            relatedSpaceNames = self.stateSpaceCfg.spaceModules[sm].RELATED_SPACES
280
            relatedSpaceNames = self.stateSpaceCfg.spaceModules[sm].RELATED_SPACES
252
            relatedSpaces = {}
281
            relatedSpaces = {}
253
            for rsname in relatedSpaceNames:
282
            for rsname in relatedSpaceNames:
254
                relatedSpaces[rsname] = self.stateSpaceCfg.spaceModules[rsname]
283
                relatedSpaces[rsname] = self.stateSpaceCfg.spaceModules[rsname]
255
            setattr(sm, '__RELATED_SPACES__', relatedSpaces)
284
            setattr(self.stateSpaceCfg.spaceModules[sm], '__RELATED_SPACES__', relatedSpaces)
256
           
285
 
257
 
286