Subversion Repositories HomeAutomation

Rev

Rev 748 | Go to most recent revision | Blame | Last modification | View Log | SVN | RSS feed

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