Rev 750 | Go to most recent revision | Blame | Last modification | View Log | SVN | RSS feed
############################################################# Daemon configuration############################################################import logging as logimport pickleimport hashlibimport osimport impimport refrom ConfigParser import ConfigParserimport filtersimport statespacesfrom CanPktHandlerBase import CanPktHandlerBasefrom CanPktHandler1 import CanPktHandler1from NodeIfSerial import NodeIfSerialfrom NodeIfTCP import NodeIfTCPfrom NodeIfUDP import NodeIfUDPfrom NodeIfTCPTLS import NodeIfTCPTLSfrom NodeIfCanStim import NodeIfCanStimfrom TCPServer1 import TCPServer1from TCPTLSServer import TCPTLSServerfrom CanCtldServer import CanCtldServerclass DynamicModuleCfg:"""Dynamic module manager"""modSubDir = NoneCHECKSUM_FILE = 'checksums'CHECKSUM_SECTION = 'SHA-1_CHECKSUMS'def __init__(self, modSubDir):self.modSubDir = modSubDirself.checkSumFile = modSubDir + '/' + self.CHECKSUM_FILEif not os.path.exists(self.checkSumFile):self.__createCsumsFile()def loadModule(self, className):pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'log.debug('Reading from ' + pFileName)fp = open(pFileName, 'r')p = pickle.Unpickler(fp)loadedMod = p.load()fp.close()if not self.__verifyCheckSum(className, pFileName):print 'Invalid checksum'return Noneelse:return loadedModdef loadModules(self, config = None):subDirFiles = os.listdir(os.getcwd() + '/' + self.modSubDir)p = re.compile('.p$', re.IGNORECASE)modFiles = [elem for elem in subDirFiles if p.search(elem) is not None]modNames = []for mfName in modFiles:modNames.append(mfName.split('.')[0])log.debug('Found modules: ' + str(modNames))myMods = {}for mName in modNames:classObj = self.loadModule(mName)if classObj is not None:myMods[mName] = classObjreturn myModsdef saveModule(self, className, classObj):pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'log.debug('Writing to ' + pFileName)fp = open(pFileName, 'w')p = pickle.Pickler(fp)p.dump(classObj)fp.close()self.__writeCheckSum(className, pFileName)def __doCheckSum(self, filename):f = open(filename, 'r')data = f.read()f.close()hasher = hashlib.sha1()hasher.update(data)digest = hasher.hexdigest()return digestdef __createCsumsFile(self):csumsfile = open(self.checkSumFile, 'w')csumsfile.write('[' + self.CHECKSUM_SECTION + ']\n')csumsfile.close()def __writeCheckSum(self, entryname, filename):csumsfile = open(self.checkSumFile, 'r+')csumcfg = ConfigParser()csumcfg.readfp(csumsfile)digest = self.__doCheckSum(filename)csumcfg.set(self.CHECKSUM_SECTION, entryname, digest)csumsfile.seek(0)csumcfg.write(csumsfile)def __verifyCheckSum(self, entryname, filename):csumsfile = open(self.checkSumFile, 'r')csumcfg = ConfigParser()csumcfg.readfp(csumsfile)digest = csumcfg.get(self.CHECKSUM_SECTION, entryname)cur_digest = self.__doCheckSum(filename)log.debug('Old checksum ' + digest + '\nNew checksum: ' + cur_digest)if cur_digest == digest:return Truereturn Falsedef importModule(self, className, requiredAttributes):"""Imports a given class from the module with the same name """codeFile = os.getcwd() + '/' + self.modSubDir + '/' + className + '.py'mod = imp.load_source(self.modSubDir + '.' + className, codeFile)newClass = eval('mod.' + className)()for ra in requiredAttributes:if not hasattr(newClass, ra):print className, ': missing required symbol \"' + ra + '\"'return Noneself.saveModule(className, newClass)return newClassclass FilterCfg:"""Filter resource manager"""REQUIRED_ATTRIBUTES = ['ASSOCIATED_SPACES', 'DESCRIPTIVE_NAME','attach', 'detach', 'filter']dynamicModuleCfg = NoneFILTER_SUBDIR = 'filters'filterModules = {}def __init__(self):self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)def loadFilter(self, name):newFilt = self.dynamicModuleCfg.loadModule(name)if newFilt is not None:self.filterModules[name] = newFiltreturn Trueelse:return Falsedef loadFilters(self, config = None):self.filterModules = self.dynamicModuleCfg.loadModules()for fM in self.filterModules:log.debug(fM)def __saveFilter(self, className, classObj):self.dynamicModuleCfg.saveModule(className, classObj)def saveFilters(self):for className in self.filterModules:self.__saveFilter(className, self.filterModules[className])def importFilter(self, className):"""Imports a given filter definition """classObj = self.dynamicModuleCfg.importModule(className, self.REQUIRED_ATTRIBUTES)if classObj is not None:print 'Imported: ' + classObj.DESCRIPTIVE_NAMEreturn Trueelse:return Falseclass StateSpaceCfg:"""State space resource manager"""REQUIRED_ATTRIBUTES = ['DESCRIPTIVE_NAME', 'RELATED_SPACES''load', 'reset', 'run', 'unload']dynamicModuleCfg = NoneFILTER_SUBDIR = 'statespaces'spaceModules = {}def __init__(self):self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)def loadSpace(self, name):newSpace = self.dynamicModuleCfg.loadModule(name)if newSpace is not None:self.spaceModules[name] = newFiltreturn Trueelse:return Falsedef loadSpaces(self, config = None):self.spaceModules = self.dynamicModuleCfg.loadModules()for sM in self.spaceModules:log.debug(sM)def __saveSpace(self, className, classObj):self.dynamicModuleCfg.saveModule(className, classObj)def saveSpaces(self):for className in self.spaceModules:self.__saveSpace(className, self.spaceModules[className])def importSpace(self, name):"""Imports a given state space definition file """classObj = self.dynamicModuleCfg.importModule(name, self.REQUIRED_ATTRIBUTES)if classObj is not None:print 'Imported: ' + classObj.DESCRIPTIVE_NAMEreturn Trueelse:return Falseclass DaemonConfig:stateSpaceCfg = NonefilterCfg = NonepktHandler = NonefilterChain = []nodeInterfaces = []nodeInterfaceMap = {}serverDaemons = []INTERFACE_TYPES = {'serial' : NodeIfSerial, 'tcp' : NodeIfTCP,'udp' : NodeIfUDP, 'sim' : NodeIfCanStim,'tcptls' : NodeIfTCPTLS}SERVER_TYPES = {'tcpd' : TCPServer1, 'tcptlsd' : TCPTLSServer,'canctld' : CanCtldServer}def __init__ (self):self.filterCfg = FilterCfg()self.stateSpaceCfg = StateSpaceCfg()self.pktHandler = CanPktHandler1(self)def load(self):self.stateSpaceCfg.loadSpaces()self.filterCfg.loadFilters()self.__setupFilterBindings()self.__setupStateSpaceRelations()self.__setupFilterChain()def save(self):self.stateSpaceCfg.saveSpaces()self.filterCfg.saveFilters()def addInterface(self, type, cfg = None):""" addInterfacetype - a valid interface type namecfg - interface configurationreturns: True on success, False otherwise """if not self.INTERFACE_TYPES.has_key(type):log.debug('addInterface called with invalid interface type')return Falsecfg = self.INTERFACE_TYPES[type].DEFAULT_CONFIGnodeIf = self.INTERFACE_TYPES[type](self.pktHandler, cfg)self.nodeInterfaces.append(nodeIf)return Truedef remInterface(self, name):passdef addServerDaemon(self, type, cfg = None):if not self.SERVER_TYPES.has_key(type):log.debug('addServerDaemon called with invalid daemon type')return Falseserverd = self.SERVER_TYPES[type]() # actung!return Truedef remServerDaemon(self, name):passdef __setupFilterChain(self):self.filterChain = ['DefaultFilter']def __setupFilterBindings(self):for f in self.filterCfg.filterModules.values():assocSpaces = []for s in f.ASSOCIATED_SPACES:if self.stateSpaceCfg.spaceModules.has_key(s):assocSpaces.append(self.stateSpaceCfg.spaceModules[s])else:print 'WARNING: Reference to undefined state space: ' + ssetattr(f, '__ASSOCIATED_SPACES__', assocSpaces)def __setupStateSpaceRelations(self):for sm in self.stateSpaceCfg.spaceModules:relatedSpaceNames = self.stateSpaceCfg.spaceModules[sm].RELATED_SPACESrelatedSpaces = {}for rsname in relatedSpaceNames:relatedSpaces[rsname] = self.stateSpaceCfg.spaceModules[rsname]setattr(self.stateSpaceCfg.spaceModules[sm], '__RELATED_SPACES__', relatedSpaces)