Rev 739 | Go to most recent revision | 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 = {}help_command_map = {}def __init__ (self):self.command_list = [['help', self.helpCmd, 'display help'],['log', self.logCmd, 'log control: \"help log\"'],['exec', self.execCmd, 'run command listing <filename>\n'],['filter', self.filterCmd, 'filter commands: \"help filter\"'],['state', self.stateCmd, 'state commands: \"help state\"\n'],['addif', self.ifAddCmd, 'add interface: \"help addif\"'],['remif', self.ifRemCmd, 'remove interface <name>'],['ifup', self.ifUpCmd, 'bring up interface <name>'],['ifdown', self.ifDownCmd, 'bring down interface <name>\n'],['addbrigde', self.addBridgeCmd, 'add bridge: \"help addbridge\"'],['rembridge', self.remBridgeCmd, 'remove bridge <name>\n'],['tcpd', self.tcpdCmd, 'tcpd server control: \"help tcpd\"'],['tlsd', self.tlsdCmd, 'tlsd server control: \"help tlsd\"'],['canctld', self.canCtldCmd, '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, 'simulator commands: \"help sim\"']]index = 0for cmd in self.command_list:self.command_map[cmd[0]] = indexindex += 1logHelp = 'not implemented'stateHelp = 'not implemented'addifHelp = 'not implemented'addbridgeHelp = 'not implemented'tcpdHelp = 'not implemented'tlsdHelp = 'not implemented'canctldHelp = 'not implemented'simHelp = 'not implemented'self.help_command_map = {'log' : logHelp,'state' : stateHelp,'addif' : addifHelp,'addbridge' : addbridgeHelp,'tcpd' : tcpdHelp,'tlsd' : tlsdHelp,'canctld' : canctldHelp,'sim' : 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 = 20-len(refstr)for i in range(1,endpos):if i == endpos-5:spcstr += ':'else:spcstr += ' 'return (spcstr+str)def helpCmd(self, *args):args = args[0]if len(args) < 1:quitStr = 'quit, exit'print quitStr, self.__rightAdjust(quitStr, 'shutdown pyCanDaemon')for cmd in self.command_list:print cmd[0], self.__rightAdjust(cmd[0], cmd[2])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):cmd = 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 deletedef stateCmd(self, *args):cmd = args[0]spaceName = args[1]if 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 statespacedef ifAddCmd(self, *args):print 'not implemented'def ifRemCmd(self, *args):print 'not implemented'def ifUpCmd(self, *args):print 'not implemented'def ifDownCmd(self, *args):print 'not implemented'passdef addBridgeCmd(self, *args):print 'not implemented'def remBridgeCmd(self, *args):print 'not implemented'def tcpdCmd(self, *args):print 'not implemented'def tlsdCmd(self, *args):print 'not implemented'def canCtldCmd(self, *args):print 'not implemented'def statusCmd(self, *args):print 'not implemented'def statsCmd(self, *args):print 'not implemented'def nodesCmd(self, *args):print 'not implemented'def filterlistCmd(self, *args):print 'not implemented'def simCmd(self, *args):print 'not implemented'def logCmd(self, *args):print 'not implemented'def execCmd(self, *args):passdef 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:demoPath = os.path.dirname(__file__)os.chdir(demoPath)except:returnprint 'INIT: Start logging'log.basicConfig(level=log.DEBUG)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 = aprint '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_CONFIGself.nodeIf = NodeIfCanStim(ifConfig, pktHandler, self.ifNotifier)# ifConfig = NodeIfSerial.DEFAULT_CONFIGatexit.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('> ').strip().lower()cmd = input.split(' ')if len(cmd[0]) < 2:continueif 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]]][1](cmd[1:])else:print 'unknown command: ' + cmd[0]""" -- suggested commands -- p n = priority to implement (1 is highest)base: (p 1)filter add <name>filter rem <name>state add <name>state rem <name>state reset <name>node interfaces: (p 1)addif <serial/sim/udp/telnet> <options> (help protocol gives options)remif <name> - delete an interfaceifup <name> - bring up an interfaceifdown <name> - bring down an interfacebridging: (p 2)addbridge <name> <ifname1> <ifname2> <ifname3> ... - create if bridgerembridge <name>servers:tcpd start [port] - raw tcp (telnet, compat) server, all pkts (p 1)tcpd stoptlsd start [port] - tcp+tls server, all pkts (p 2)tlsd stopcanctld start [port] - pyCanGUI server (tcp/tls) (p 2)canctld stopinfo commands: (p 3)status - shows active settings, interfaces, serversstats - shows some traffic statisticsnodes - shows active nodesfilters - shows active filtersstate [name] - shows active states, opt specific state info\log - log control (TBD)simulator commands: (p 2)simrecord <file> - record incoming packetssimplay <file> [timescale] - play recorded stream, opt accel time:simadd <nodeid> (nodetype)simrem <nodeid>simsave <config>simload <config>"""""" -- other features --startup.cfg - script to run at startup (command listing)ie: ifup 0tlsd startcanguid startconfig.cfg - last daemon config (param override)default.cfg - default daemon config (only read if config.cfg does not exist)"""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()