Rev 740 | Blame | Last modification | View Log | SVN | RSS feed
#!/bin/env pythonimport osimport sysimport logging as logimport getoptimport atexitimport timefrom CanPktHandlerBase import CanPktHandlerBasefrom CanPktHandler1 import CanPktHandler1from NodeIfBase import NodeIfBasefrom NodeIfCanStim import NodeIfCanStimfrom NodeIfSerial import NodeIfSerialfrom DaemonConfig import DaemonConfigdaemonApp = Noneclass CanDaemon():cfg = NonenodeIf = NoneifNotifier = Noneterminated = Falsecommand_list = []command_map = {}CMDLIST_NAME = 0CMDLIST_HANDLER = 1CMDLIST_PARAMINFO = 2CMDLIST_HELP = 3logHelp = 'usage:\t log [options]\n\n' \'\t options:\n' \'\t level <num>, where: 0 < num < 3\n'stateHelp = 'usage: state [name/add/rem]'filterHelp = 'usage: filter [name/add/rem]'addifHelp = 'usage: addif [name] [options]'addbridgeHelp = 'usage: addbridge [interface names]'tcpdHelp = 'usage: tcpd [start/stop/configure] [options]'tlsdHelp = 'usage: tlsd [start/stop/configure] [options]'canctldHelp = 'usage: canctld [start/stop/configure] [options]'simHelp = 'usage: sim [record/play/add/rem/save/load] [options]'help_command_map = {}logOptions = {}ifOptions = {}bridgeOptions = {}tcpdOptions = {}tlsdOptions = {}canctldOptions = {}simOptions = {}logValidOptions = {'level' : ['range', 0, 3]}ifValidOptions = {'type' : ['alt', 'serial','udp']}ifSerialOptions = {'' : []}ifCanStimOptions = {'' : []}ifTelnetOptions = {'' : []}ifTcpTlsOptions = {'' : []}ifUDPOptions = {'' : []}bridgeValidOptions = {'' : ['']}tcpdValidOptions = {'' : []}tlsdValidOptions = {'' : []}canctldValidOptions = {'' : []}simValidOptions = {'' : []}def __init__ (self):self.command_list = [['help', self.helpCmd, '', 'display help'],['log', self.logCmd, '<options>', 'log control: \"help log\"'],['exec', self.execCmd, '<filename>', 'run command listing\n'],['filter', self.filterCmd, '<cmd>', 'filter commands: \"help filter\"'],['state', self.stateCmd, '<cmd>', 'state commands: \"help state\"\n'],['addif', self.ifAddCmd, '<options>', 'add interface: \"help addif\"'],['remif', self.ifRemCmd, '<name>', 'remove interface'],['ifup', self.ifUpCmd, '<name>', 'bring up interface'],['ifdown', self.ifDownCmd, '<name>', 'bring down interface\n'],['addbrigde', self.addBridgeCmd, '<options>', 'add bridge: \"help addbridge\"'],['rembridge', self.remBridgeCmd, '<id>', 'remove bridge\n'],['tcpd', self.tcpdCmd, '<cmd>', 'tcpd server control: \"help tcpd\"'],['tlsd', self.tlsdCmd, '<cmd>', 'tlsd server control: \"help tlsd\"'],['canctld', self.canCtldCmd, '<cmd>', 'canctld server control: \"help canctld\"\n'],['status', self.statusCmd, '', 'show daemon status'],['stats', self.statsCmd, '', 'show statistics\n'],['nodelist', self.nodesCmd, '', 'list can nodes'],['filterlist', self.filterlistCmd, '', 'list active filters\n'],['sim', self.simCmd, '<cmd>', 'simulator commands: \"help sim\"']]index = 0for cmd in self.command_list:self.command_map[cmd[0]] = indexindex += 1self.help_command_map = {'log' : self.logHelp,'filter' : self.filterHelp,'state' : self.stateHelp,'addif' : self.addifHelp,'addbridge' : self.addbridgeHelp,'tcpd' : self.tcpdHelp,'tlsd' : self.tlsdHelp,'canctld' : self.canctldHelp,'sim' : self.simHelp}self.cfg = DaemonConfig()class IfNotifier():""" Used by if threads to send messages to the main program thread """UNDEFINED = 0TERMINATE = 1def notify(self, msg):if msg == self.TERMINATE:print 'Main terminate notify'self.terminated = Trueelse:print 'UNDEFINED NOTIFY'def __rightAdjust(self, refstr, str):spcstr = ''endpos = 25-len(refstr)for i in range(1,endpos):if i == endpos-5:spcstr += ':'else:spcstr += ' 'return (spcstr+str)def helpCmd(self, *args):try:args = args[0]except:args = []if len(args) < 1:quitStr = 'quit, exit'print quitStr, self.__rightAdjust(quitStr, 'shutdown pyCanDaemon')for cmd in self.command_list:cmdstr = cmd[self.CMDLIST_NAME] + ' ' + cmd[self.CMDLIST_PARAMINFO]print cmdstr, \self.__rightAdjust(cmdstr, cmd[self.CMDLIST_HELP])elif len(args) < 2:subCmd = args[0]if self.help_command_map.has_key(subCmd):print self.help_command_map[subCmd]else:print 'no help for ' + subCmdelse:print 'usage: help [topic]'def filterCmd(self, *args):try:args = args[0]except:args = []log.debug('filterCmd ' + str(args))if len(args) < 2:print 'Invalid arguments\n' + self.filterHelpreturncmd = args[0]filterName = args[1]# FIXME: verifyif cmd == 'add':print 'Importing filter: ' + filterNameself.cfg.filterCfg.importFilter(filterName)elif cmd == 'rem' or cmd == 'remove':print 'Deleting filter: ' + filterName# FIXME: actually deleteraise 'Not implemented'def stateCmd(self, *args):try:args = args[0]except:args = []log.debug('stateCmd ' + str(args))if len(args) < 2:print 'Invalid arguments\n' + self.stateHelpreturncmd = args[0]spaceName = args[1]# FIXME: verifyif cmd == 'add':print 'Importing state space: ' + spaceNameself.cfg.stateSpaceCfg.importSpace(spaceName)elif cmd == 'rem' or cmd == 'remove':print 'Deleting state space: ' + spaceName# FIXME: actually delete statespaceraise 'Not implemented'def ifAddCmd(self, *args):raise 'not implemented'def ifRemCmd(self, *args):raise 'not implemented'def ifUpCmd(self, *args):raise 'not implemented'def ifDownCmd(self, *args):raise 'not implemented'def addBridgeCmd(self, *args):raise 'not implemented'def remBridgeCmd(self, *args):raise 'not implemented'def tcpdCmd(self, *args):raise 'not implemented'def tlsdCmd(self, *args):raise 'not implemented'def canCtldCmd(self, *args):raise 'not implemented'def statusCmd(self, *args):raise 'not implemented'def statsCmd(self, *args):raise 'not implemented'def nodesCmd(self, *args):raise 'not implemented'def filterlistCmd(self, *args):raise 'not implemented'def simCmd(self, *args):raise 'not implemented'def logCmd(self, *args):raise 'not implemented'def execCmd(self, *args):raise 'not implemented'def parseCommand(self, cmdstr):incmd = cmdstr.strip()cmd = incmd.split(' ')if len(cmd[0]) < 2:returncmd[0] = cmd[0].lower()if cmd[0] == 'quit' or cmd[0] == 'exit':self.terminated = Trueelif self.command_map.has_key(cmd[0]):self.command_list[self.command_map[cmd[0]]][self.CMDLIST_HANDLER](cmd[1:])else:print 'unknown command: ' + cmd[0]def exitHelper(self):if self.nodeIf is not None and self.nodeIf.running():self.nodeIf.stop()def exceptHelper(self, type, value, tb):import tracebacktraceback.print_exception(type, value, tb)print '\nException in main program, shutting down threads'self.terminated = Trueself.exitHelper()# sys.exit(-1)def run(self):try:myPath = os.path.dirname(__file__)os.chdir(myPath)except:returnprint 'INIT: Start logging'log.basicConfig(level=log.DEBUG)"""command parameters only dictate verbosity and use of config file"""print 'INIT: Get config options from command line / config file'try:opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])except getopt.GetoptError:print 'Invalid usage'usage()sys.exit(2)# output = None# verbose = Falsefor o, a in opts:if o == "-v":pass# verbose = Trueif o in ("-h", "--help"):usage()sys.exit()if o in ("-o", "--output"):pass# output = a"""load config defaults, or last config if exists""""""run startup.cfg"""# print 'INIT: Loading filters and spaces'# self.cfg.filterCfg.importFilter('DefaultFilter')# self.cfg.stateSpaceCfg.importSpace('DefaultStateSpace')# self.cfg.stateSpaceCfg.loadSpaces()# self.cfg.filterCfg.loadFilters()# self.cfg.setupFilterBindings()# self.cfg.setupFilterChain()# print 'INIT: Starting selected can interface'# ''' nodeif thread launch '''# self.ifNotifier = self.IfNotifier()# pktHandler = CanPktHandler1(self.cfg)## ifConfig = NodeIfCanStim.DEFAULT_CONFIG# self.nodeIf = NodeIfCanStim(ifConfig, pktHandler, self.ifNotifier)# # ifConfig = NodeIfSerial.DEFAULT_CONFIG## atexit.register(self.exitHelper)# sys.excepthook = self.exceptHelper# self.nodeIf = NodeIfSerial(pktHandler, ifConfig)## if not self.nodeIf.start():# print 'FATAL: Failed to initialize node interface.'# print 'This may indicate that the interface is unavailable, ' \# 'or that you do not have permission to access it.'# sys.exit(-1)print 'Initialize/gather info on connected can nodes and load associated state'print 'Start selected TCP and UDP server(s)'# server threads launchprint 'CanDaemon v1 ready'print 'Enter command or type \"help\" for a list of commands'while not self.terminated:input = raw_input('> ')self.parseCommand(input)print 'Shutdown'# if self.nodeIf.running():# print 'Stopping If thread'# self.nodeIf.stop()# self.cfg.stateSpaceCfg.saveSpaces()# self.cfg.filterCfg.saveFilters()print 'Waiting 0.1..'time.sleep(0.1) # wait for threadsprint 'Terminating'sys.exit(0) # will except if there are threads remaining#---------------------------------------------------------------------------def main():daemonApp = CanDaemon()# install_thread_excepthook()daemonApp.run()#---------------------------------------------------------------------------if __name__ == '__main__':__name__ = 'Main'main()