Subversion Repositories HomeAutomation

Rev

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

  1. #!/bin/env python
  2.  
  3. import os
  4. import sys
  5. import logging as log
  6. import getopt
  7. import atexit
  8. import time
  9.  
  10. from CanPktHandlerBase import CanPktHandlerBase
  11. from CanPktHandler1 import CanPktHandler1
  12.  
  13. from NodeIfBase import NodeIfBase
  14. from NodeIfCanStim import NodeIfCanStim
  15. from NodeIfSerial import NodeIfSerial
  16.  
  17. from DaemonConfig import DaemonConfig
  18.  
  19. daemonApp = None
  20.  
  21. class CanDaemon():
  22.    
  23.     nodeIf = None
  24.     ifNotifier = None
  25.     terminated = False
  26.     command_list = []
  27.  
  28.     def __init__ (self):
  29.         pass
  30.    
  31.     class IfNotifier():
  32.         """ Used by if threads to send messages to the main program thread """
  33.         UNDEFINED = 0
  34.         TERMINATE = 1
  35.    
  36.         def notify(self, msg):
  37.             if msg == self.TERMINATE:
  38.                 print 'Main terminate notify'
  39.                 self.terminated = True
  40.             else:
  41.                 print 'UNDEFINED NOTIFY'
  42.        
  43.    
  44.     def __rightAdjust(self, refstr, str):
  45.         spcstr = ''
  46.         endpos = 20-len(refstr)
  47.         for i in range(1,endpos):
  48.             if i == endpos-5:
  49.                 spcstr += ':'
  50.             else:
  51.                 spcstr += ' '
  52.         return (spcstr+str)
  53.    
  54.     def helpCmd(self, *args):
  55.         quitStr = 'quit, exit'
  56. #        print quitStr, self.__rightAdjust(quitStr, 'shutdown pyCanDaemon')
  57. #        for cmd in cmdNames:
  58. #            print cmd, self.__rightAdjust(cmd, command_map[cmd][1])
  59.        
  60.     def filterCmd(self, *args):
  61.         pass
  62.    
  63.     def stateCmd(self, *args):
  64.         pass
  65.    
  66.     def ifAddCmd(self, *args):
  67.         pass
  68.    
  69.     def ifRemCmd(self, *args):
  70.         pass
  71.    
  72.     def ifUpCmd(self, *args):
  73.         pass
  74.    
  75.     def ifDownCmd(self, *args):
  76.         pass
  77.    
  78.     def addBridgeCmd(self, *args):
  79.         pass
  80.    
  81.     def remBridgeCmd(self, *args):
  82.         pass
  83.    
  84.     def tcpdCmd(self, *args):
  85.         pass
  86.    
  87.     def tlsdCmd(self, *args):
  88.         pass
  89.    
  90.     def canCtldCmd(self, *args):
  91.         pass
  92.    
  93.     def statusCmd(self, *args):
  94.         pass
  95.    
  96.     def statsCmd(self, *args):
  97.         pass
  98.    
  99.     def nodesCmd(self, *args):
  100.         pass
  101.    
  102.     def filterlistCmd(self, *args):
  103.         pass
  104.    
  105.     def simCmd(self, *args):
  106.         pass
  107.    
  108.     def logCmd(self, *args):
  109.         pass
  110.    
  111.     def execCmd(self, *args):
  112.         pass
  113.    
  114.     def exitHelper(self):
  115.         if self.nodeIf is not None and self.nodeIf.running():
  116.             self.nodeIf.stop()
  117.            
  118.     def exceptHelper(self, type, value, tb):
  119.         import traceback
  120.         traceback.print_exception(type, value, tb)
  121.         print '\nException in main program, shutting down threads'
  122.         self.terminated = True
  123.         self.exitHelper()
  124.  #       sys.exit(-1)
  125.  
  126.     def run(self):
  127.         try:
  128.             demoPath = os.path.dirname(__file__)
  129.             os.chdir(demoPath)
  130.         except:
  131.             return
  132.        
  133.         print 'INIT: Start logging'
  134.         log.basicConfig(level=log.DEBUG)
  135.        
  136.         print 'INIT: Get config options from command line / config file'
  137.         cfg = DaemonConfig()
  138.        
  139.         try:
  140.             opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
  141.         except getopt.GetoptError:
  142.             print 'Invalid usage'
  143.             usage()
  144.             sys.exit(2)
  145.      #   output = None
  146.      #   verbose = False
  147.         for o, a in opts:
  148.             if o == "-v":
  149.                 pass
  150.      #           verbose = True
  151.             if o in ("-h", "--help"):
  152.                 usage()
  153.                 sys.exit()
  154.             if o in ("-o", "--output"):
  155.                 pass
  156.     #            output = a
  157.    
  158.         print 'INIT: Loading filters and spaces'
  159.   #      cfg.filterCfg.importFilter('DefaultFilter')
  160.   #      cfg.stateSpaceCfg.importSpace('DefaultStateSpace')
  161.         cfg.stateSpaceCfg.loadSpaces()
  162.         cfg.filterCfg.loadFilters()
  163.         cfg.setupFilterBindings()
  164.         cfg.setupFilterChain()
  165.        
  166.         print 'INIT: Starting selected can interface'
  167.         ''' nodeif thread launch '''
  168.         self.ifNotifier = self.IfNotifier()
  169.         pktHandler = CanPktHandler1(cfg)
  170.        
  171.         ifConfig = NodeIfCanStim.DEFAULT_CONFIG
  172.         self.nodeIf = NodeIfCanStim(ifConfig, pktHandler, self.ifNotifier)
  173.  #       ifConfig = NodeIfSerial.DEFAULT_CONFIG
  174.    
  175.         atexit.register(self.exitHelper)
  176.         sys.excepthook = self.exceptHelper
  177.  #       self.nodeIf = NodeIfSerial(pktHandler, ifConfig)
  178.        
  179.         if not self.nodeIf.start():
  180.             print 'FATAL: Failed to initialize node interface.'
  181.             print 'This may indicate that the interface is unavailable, ' \
  182.                   'or that you do not have permission to access it.'
  183.             sys.exit(-1)
  184.  
  185.         print 'Initialize/gather info on connected can nodes and load associated state'
  186.         print 'Start selected TCP and UDP server(s)'
  187.         # server threads launch
  188.        
  189.         print 'CanDaemon v1 ready'
  190.         print 'Enter command or type \"help\" for a list of commands'
  191.        
  192.         global command_map
  193.         command_map = {'help' : (self.helpCmd, 'display help'),
  194.                        'filter' : (self.filterCmd, 'filter commands: \"help filter\"'),
  195.                        'state' : (self.stateCmd, 'state commands: \"help state\"'),
  196.                        'addif' : (self.ifAddCmd, 'add interface: \"help addif\"'),
  197.                        'remif' : (self.ifRemCmd, 'remove interface <name>'),
  198.                        'ifup' : (self.ifUpCmd, 'bring up interface <name>'),
  199.                        'ifdown' : (self.ifDownCmd, 'bring down interface <name>'),
  200. #                       'addbrigde' : (self.addBridgeCmd, 'add bridge: \"help addbridge\"'),
  201. #                       'rembridge' : (self.remBridgeCmd, 'remove bridge <name>'),
  202.                        'tcpd' : (self.tcpdCmd, 'tcpd server control: \"help tcpd\"'),
  203. #                       'tlsd' : (self.tlsdCmd, 'tlsd server control: \"help tlsd\"'),
  204. #                       'canctld' : (self.canCtldCmd, 'canctld server control: \"help canctld\"'),
  205. #                       'status' : (self.statusCmd, 'show daemon status'),
  206. #                       'stats' : (self.statsCmd, 'show statistics'),
  207. #                       'nodelist' : (self.nodesCmd, 'list can nodes'),
  208. #                       'filterlist' : (self.filterlistCmd, 'list active filters'),
  209. #                       'sim' : (self.simCmd, 'simulator commands: \"help sim\"'),
  210. #                       'log' : (self.logCmd, 'log control: \"help log\"'),
  211. #                       'exec' : (self.execCmd,  'run command listing <filename>')}
  212.  
  213.         while not self.terminated:
  214.             input = raw_input('> ').strip().lower()
  215.             cmd = input.split(' ')
  216.             if cmd[0] == 'quit' or cmd[0] == 'exit':
  217.                 self.terminated = True
  218.             elif command_map.has_key(cmd[0]):
  219.                 command_map[cmd[0]][0](cmd[1:])
  220.             else:
  221.                 print 'Unknown command: ' + cmd[0]
  222.  
  223.         """ -- suggested commands -- p n = priority to implement (1 is highest)
  224.            base: (p 1)
  225.            filter add <name>
  226.            filter rem <name>
  227.            state add <name>
  228.            state rem <name>
  229.            state reset <name>
  230.            
  231.                 node interfaces:  (p 1)
  232.            addif <serial/sim/udp/telnet> <options> (help protocol gives options)
  233.            remif <name> - delete an interface
  234.            ifup <name> - bring up an interface
  235.            ifdown <name> - bring down an interface
  236.            
  237.                 bridging: (p 2)
  238.            addbridge <name> <ifname1> <ifname2> <ifname3> ... - create if bridge
  239.            rembridge <name>
  240.            
  241.                 servers:
  242.            tcpd start [port] - raw tcp (telnet, compat) server, all pkts  (p 1)
  243.            tcpd stop
  244.            tlsd start [port] - tcp+tls server, all pkts  (p 2)
  245.            tlsd stop
  246.            canctld start [port] - pyCanGUI server (tcp/tls)  (p 2)
  247.            canctld stop
  248.            
  249.            info commands: (p 3)
  250.            status - shows active settings, interfaces, servers
  251.            stats - shows some traffic statistics
  252.            nodes - shows active nodes
  253.            filters - shows active filters
  254.            state [name] - shows active states, opt specific state info\
  255.            log - log control (TBD)
  256.            
  257.            simulator commands: (p 2)
  258.            simrecord <file> - record incoming packets
  259.            simplay <file> [timescale] - play recorded stream, opt accel time:
  260.            simadd <nodeid> (nodetype)
  261.            simrem <nodeid>
  262.            simsave <config>
  263.            simload <config>
  264.        """
  265.  
  266.         """ -- other features --
  267.            startup.cfg - script to run at startup (command listing)
  268.            ie: ifup 0
  269.                tlsd start
  270.                canguid start
  271.            config.cfg - last daemon config (param override)
  272.            default.cfg - default daemon config (only read if config.cfg does not exist)
  273.        """
  274.  
  275.         print 'Shutdown'
  276.         if self.nodeIf.running():
  277.             print 'Stopping If thread'
  278.             self.nodeIf.stop()
  279.  
  280.         cfg.stateSpaceCfg.saveSpaces()
  281.         cfg.filterCfg.saveFilters()
  282.        
  283.         print 'Waiting 0.1..'
  284.         time.sleep(0.1) # wait for threads
  285.         print 'Terminating'
  286.         sys.exit(0) # will except if there are threads remaining
  287.  
  288. #---------------------------------------------------------------------------
  289.  
  290. def main():
  291.     daemonApp = CanDaemon()
  292. #    install_thread_excepthook()
  293.     daemonApp.run()
  294.  
  295. #---------------------------------------------------------------------------
  296.  
  297. if __name__ == '__main__':
  298.     __name__ = 'Main'
  299.     main()
  300.