1f1f5cc7153fb4987f4bf6ada2ccee03c5b7f3e0
[ais.git] / bin / inputs / peers.py
1 # -*- coding: utf-8 -*-
2 '''
3 Peers definition
4 '''
5
6 import logging
7 import pprint
8 from ais.ntools import str_split_column_ipv6
9 from ais.inputs.config import SOURCES
10 #from ais.inputs.udp import UdpService
11 #from ais.inputs.serialin import SerialService
12
13 UDPIN_HLPORT = {}
14 __source_normalized__ = False
15
16 # SOURCES normalization & checks
17 def _normalize_sources():
18     global __source_normalized__
19     if __source_normalized__:
20         return
21     logging.debug('SOURCES (raw):\n%s', pprint.pformat(SOURCES))
22     for id4, settings in SOURCES.iteritems():
23         assert len(id4) == 4, \
24             'Invalid ID %s in SOURCES. It should be 4 characters long.'
25
26         try:
27             in_ = settings['in']
28         except KeyError:
29             continue
30     
31         assert type(in_) == str, \
32             "SOURCES['%s']['in'] should be of type str, not %s'." % \
33             (id4, type(in_))
34         in_ = settings.get('in')
35         spl = str_split_column_ipv6(in_)
36         protocol, parameters = spl[0], spl[1:]
37         assert parameters, \
38             "SOURCES['%s']['in'] should contain parameters after %s" % \
39             (id4, protocol)
40            
41         if protocol == 'udp':
42             assert len(parameters) == 4, \
43                 "SOURCES['%s']['in'] udp: protocol requires 4 parameters." % \
44                 id4
45             host_local = parameters[0]
46             if host_local == '*':
47                 host_local = ''
48             port_local = parameters[1]
49             assert port_local.isdigit(), \
50                 "SOURCES['%s']['in'] udp: illegal local port" % \
51                 id4
52             port_local = int(port_local)
53             host_remote = parameters[2]
54             if host_remote == '*':
55                 host_remote = ''
56             port_remote = parameters[3]
57             source_port_discreminate = False
58             if port_remote == '*':
59                 port_remote = ''
60             elif port_remote == '!':
61                 port_remote = ''
62                 source_port_discreminate = True
63             else:
64                 assert port_remote.isdigit(), \
65                     "SOURCES['%s']['in'] udp: illegal remote port" % \
66                     id4
67                 port_remote = int(port_remote)
68          
69             if port_local not in UDPIN_HLPORT:
70                 UDPIN_HLPORT[port_local] = {}
71             UDPIN_HLPORT[port_local][host_remote, port_remote] \
72                  = id4, source_port_discreminate
73             SOURCES[id4]['in'] = ('Udp', host_local, port_local, host_remote, port_remote, source_port_discreminate)
74         elif protocol == 'serial':
75             assert len(parameters) == 1, \
76                 "SOURCES['%s']['in'] serial: protocol requires 1 parameter." % \
77                 id4
78             SOURCES[id4]['in'] = ('Serial', parameters[0])
79
80         else:
81             logging.error(
82                 "Unsupported source protocol '%s' for SOURCES['%s']: %s",
83                 protocol, id4, in_)
84     __source_normalized__ = True
85     logging.debug('SOURCES (normalised):\n%s', pprint.pformat(SOURCES))
86     logging.debug('UDPIN_HLPORT:\n%s', pprint.pformat(UDPIN_HLPORT))
87
88
89 def source_get_infoin(*args):
90     '''
91     Gets a list of matching info in SOURCES[*]['in']:
92     example: get_source_infoin('Udp', '', 1234)
93       might return [ ['SRC1', '12.23.34.45', '', False],
94                      ['SRC2', '98.87.76.65', '', True]]
95     '''
96     if not __source_normalized__:
97         _normalize_sources()
98     result = []
99     for id4, source_info in SOURCES.iteritems():
100         rawin = source_info.get('in', None)
101         if not rawin:
102             continue
103         if args == rawin[:len(args)]:
104             newmatch = [id4] + [rawin[i] for i in range(len(args), len(rawin))]
105             result.append(newmatch)
106     return result
107         
108