Subversion Repositories HomeAutomation

Rev

Rev 738 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 738 Rev 739
1
#!/bin/env python
1
#!/bin/env python
2
 
2
 
3
import os
3
import os
4
import sys
4
import sys
5
import logging as log
5
import logging as log
6
import getopt
6
import getopt
7
import atexit
7
import atexit
8
import time
8
import time
9
 
9
 
10
from CanPktHandlerBase import CanPktHandlerBase
10
from CanPktHandlerBase import CanPktHandlerBase
11
from CanPktHandler1 import CanPktHandler1
11
from CanPktHandler1 import CanPktHandler1
12
 
12
 
13
from NodeIfBase import NodeIfBase
13
from NodeIfBase import NodeIfBase
14
from NodeIfCanStim import NodeIfCanStim
14
from NodeIfCanStim import NodeIfCanStim
15
from NodeIfSerial import NodeIfSerial
15
from NodeIfSerial import NodeIfSerial
16
 
16
 
17
from DaemonConfig import DaemonConfig
17
from DaemonConfig import DaemonConfig
18
 
18
 
19
daemonApp = None
19
daemonApp = None
20
 
20
 
21
class CanDaemon():
21
class CanDaemon():
22
   
22
   
23
    nodeIf = None
23
    nodeIf = None
24
    ifNotifier = None
24
    ifNotifier = None
25
    terminated = False
25
    terminated = False
-
 
26
    command_list = []
26
   
27
 
27
    class IfNotifier():
28
    def __init__ (self):
-
 
29
        pass
28
   
30
   
-
 
31
    class IfNotifier():
-
 
32
        """ Used by if threads to send messages to the main program thread """
29
        UNDEFINED = 0
33
        UNDEFINED = 0
30
        TERMINATE = 1
34
        TERMINATE = 1
31
   
35
   
32
        def notify(self, msg):
36
        def notify(self, msg):
33
            if msg == self.TERMINATE:
37
            if msg == self.TERMINATE:
34
                print 'Main terminate notify'
38
                print 'Main terminate notify'
35
                self.terminated = True
39
                self.terminated = True
36
            else:
40
            else:
37
                print 'UNDEFINED NOTIFY'
41
                print 'UNDEFINED NOTIFY'
38
       
42
       
39
    def __init__ (self):
-
 
40
        pass
-
 
41
   
-
 
42
   
-
 
43
    def usage(self):
-
 
44
        pass
-
 
45
   
-
 
46
   
-
 
47
    def helpCommands(self):
-
 
48
        print 'quit, exit     : shutdown CanDaemon'
-
 
49
        print 'help           : display help'
-
 
50
   
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
51
   
113
   
52
    def exitHelper(self):
114
    def exitHelper(self):
53
        if self.nodeIf is not None and self.nodeIf.running():
115
        if self.nodeIf is not None and self.nodeIf.running():
54
            self.nodeIf.stop()
116
            self.nodeIf.stop()
55
         
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)
56
   
125
 
57
    def run(self):
126
    def run(self):
58
        try:
127
        try:
59
            demoPath = os.path.dirname(__file__)
128
            demoPath = os.path.dirname(__file__)
60
            os.chdir(demoPath)
129
            os.chdir(demoPath)
61
        except:
130
        except:
62
            return
131
            return
63
       
132
       
64
        print 'INIT: Start logging'
133
        print 'INIT: Start logging'
65
        log.basicConfig(level=log.DEBUG)
134
        log.basicConfig(level=log.DEBUG)
66
       
135
       
67
        print 'INIT: Get config options from command line / config file'
136
        print 'INIT: Get config options from command line / config file'
68
        cfg = DaemonConfig()
137
        cfg = DaemonConfig()
69
       
138
       
70
        try:
139
        try:
71
            opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
140
            opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
72
        except getopt.GetoptError:
141
        except getopt.GetoptError:
73
            print 'Invalid usage'
142
            print 'Invalid usage'
74
            usage()
143
            usage()
75
            sys.exit(2)
144
            sys.exit(2)
76
     #   output = None
145
     #   output = None
77
     #   verbose = False
146
     #   verbose = False
78
        for o, a in opts:
147
        for o, a in opts:
79
            if o == "-v":
148
            if o == "-v":
80
                pass
149
                pass
81
     #           verbose = True
150
     #           verbose = True
82
            if o in ("-h", "--help"):
151
            if o in ("-h", "--help"):
83
                usage()
152
                usage()
84
                sys.exit()
153
                sys.exit()
85
            if o in ("-o", "--output"):
154
            if o in ("-o", "--output"):
86
                pass
155
                pass
87
    #            output = a
156
    #            output = a
88
   
157
   
89
        print 'INIT: Loading filters and spaces'
158
        print 'INIT: Loading filters and spaces'
90
  #      cfg.filterCfg.importFilter('DefaultFilter')
159
  #      cfg.filterCfg.importFilter('DefaultFilter')
91
  #      cfg.stateSpaceCfg.importSpace('DefaultStateSpace')
160
  #      cfg.stateSpaceCfg.importSpace('DefaultStateSpace')
92
        cfg.stateSpaceCfg.loadSpaces()
161
        cfg.stateSpaceCfg.loadSpaces()
93
        cfg.filterCfg.loadFilters()
162
        cfg.filterCfg.loadFilters()
94
        cfg.setupFilterBindings()
163
        cfg.setupFilterBindings()
95
        cfg.setupFilterChain()
164
        cfg.setupFilterChain()
96
       
165
       
97
        print 'INIT: Starting selected can interface'
166
        print 'INIT: Starting selected can interface'
98
        ''' nodeif thread launch '''
167
        ''' nodeif thread launch '''
99
        self.ifNotifier = self.IfNotifier()
168
        self.ifNotifier = self.IfNotifier()
100
        pktHandler = CanPktHandler1(cfg)
169
        pktHandler = CanPktHandler1(cfg)
101
       
170
       
102
        ifConfig = NodeIfCanStim.DEFAULT_CONFIG
171
        ifConfig = NodeIfCanStim.DEFAULT_CONFIG
103
        self.nodeIf = NodeIfCanStim(ifConfig, pktHandler, self.ifNotifier)
172
        self.nodeIf = NodeIfCanStim(ifConfig, pktHandler, self.ifNotifier)
104
 #       ifConfig = NodeIfSerial.DEFAULT_CONFIG
173
 #       ifConfig = NodeIfSerial.DEFAULT_CONFIG
105
   
174
   
106
        atexit.register(self.exitHelper)
175
        atexit.register(self.exitHelper)
107
 #       sys.excepthook = self.exceptHelper
176
        sys.excepthook = self.exceptHelper
108
 #       self.nodeIf = NodeIfSerial(pktHandler, ifConfig)
177
 #       self.nodeIf = NodeIfSerial(pktHandler, ifConfig)
109
       
178
       
110
        if not self.nodeIf.start():
179
        if not self.nodeIf.start():
111
            print 'FATAL: Failed to initialize node interface.'
180
            print 'FATAL: Failed to initialize node interface.'
112
            print 'This may indicate that the interface is unavailable, ' \
181
            print 'This may indicate that the interface is unavailable, ' \
113
                  'or that you do not have permission to access it.'
182
                  'or that you do not have permission to access it.'
114
            sys.exit(-1)
183
            sys.exit(-1)
115
 
184
 
116
        print 'Initialize/gather info on connected can nodes and load associated state'
185
        print 'Initialize/gather info on connected can nodes and load associated state'
117
        print 'Start selected TCP and UDP server(s)'
186
        print 'Start selected TCP and UDP server(s)'
118
        # server threads launch
187
        # server threads launch
119
       
188
       
120
        print 'CanDaemon v1 ready'
189
        print 'CanDaemon v1 ready'
121
        print 'Enter command or type \"help\" for a list of commands'
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>')}
122
 
212
 
123
        while not self.terminated:
213
        while not self.terminated:
124
            input = raw_input('> ').strip().lower()
214
            input = raw_input('> ').strip().lower()
-
 
215
            cmd = input.split(' ')
125
            if input == 'quit' or input == 'exit':
216
            if cmd[0] == 'quit' or cmd[0] == 'exit':
126
                self.terminated = True
217
                self.terminated = True
127
            elif input == 'help':
218
            elif command_map.has_key(cmd[0]):
128
                self.helpCommands()
219
                command_map[cmd[0]][0](cmd[1:])
129
            else:
220
            else:
130
                print 'Unknown command: ' + input
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
        """
131
       
274
 
132
        print 'Shutdown'
275
        print 'Shutdown'
133
        if self.nodeIf.running():
276
        if self.nodeIf.running():
-
 
277
            print 'Stopping If thread'
134
            self.nodeIf.stop()
278
            self.nodeIf.stop()
135
 
279
 
136
        cfg.stateSpaceCfg.saveSpaces()
280
        cfg.stateSpaceCfg.saveSpaces()
137
        cfg.filterCfg.saveFilters()
281
        cfg.filterCfg.saveFilters()
138
       
282
       
-
 
283
        print 'Waiting 0.1..'
139
        time.sleep(0.1) # wait for threads
284
        time.sleep(0.1) # wait for threads
-
 
285
        print 'Terminating'
140
        sys.exit(0) # will except if there are threads remaining
286
        sys.exit(0) # will except if there are threads remaining
141
 
287
 
142
#---------------------------------------------------------------------------
288
#---------------------------------------------------------------------------
143
 
289
 
144
def main():
290
def main():
145
    daemonApp = CanDaemon()
291
    daemonApp = CanDaemon()
146
#    install_thread_excepthook()
292
#    install_thread_excepthook()
147
    daemonApp.run()
293
    daemonApp.run()
148
 
294
 
149
#---------------------------------------------------------------------------
295
#---------------------------------------------------------------------------
150
 
296
 
151
if __name__ == '__main__':
297
if __name__ == '__main__':
152
    __name__ = 'Main'
298
    __name__ = 'Main'
153
    main()
299
    main()
154
 
300