Esempio n. 1
0
 def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid,
                 _data):
     if HEX_TGID == _dst_sub and _ts in GROUP_TS:
         if not _end:
             if not self.CALL_DATA:
                 logger.info(
                     '(%s) Receiving transmission to be played back from subscriber: %s',
                     _network, int_id(_src_sub))
             _tmp_data = _data
             #_tmp_data = dmr_nat(_data, _src_sub, NETWORK[_network]['LOCAL']['RADIO_ID'])
             self.CALL_DATA.append(_tmp_data)
         if _end:
             self.CALL_DATA.append(_data)
             time.sleep(2)
             logger.info(
                 '(%s) Playing back transmission from subscriber: %s',
                 _network, int_id(_src_sub))
             for i in self.CALL_DATA:
                 _tmp_data = i
                 _tmp_data = _tmp_data.replace(
                     _peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                 if GROUP_SRC_SUB:
                     _tmp_data = _tmp_data.replace(
                         _src_sub, HEX_GRP_SUB)
                 _tmp_data = self.hashed_packet(
                     NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                 # Send the packet to all peers in the target IPSC
                 self.send_to_ipsc(_tmp_data)
                 time.sleep(0.06)
             self.CALL_DATA = []
Esempio n. 2
0
 def private_voice(self, _network, _src_sub, _dst_sub, _ts, _end,
                   _peerid, _data):
     if HEX_SUB == _dst_sub and _ts in PRIVATE_TS:
         if not _end:
             if not self.CALL_DATA:
                 logger.info(
                     '(%s) Receiving transmission to be played back from subscriber: %s, to subscriber: %s',
                     _network, int_id(_src_sub), int_id(_dst_sub))
             _tmp_data = _data
             self.CALL_DATA.append(_tmp_data)
         if _end:
             self.CALL_DATA.append(_data)
             time.sleep(1)
             logger.info(
                 '(%s) Playing back transmission from subscriber: %s, to subscriber %s',
                 _network, int_id(_src_sub), int_id(_dst_sub))
             _orig_src = _src_sub
             _orig_dst = _dst_sub
             for i in self.CALL_DATA:
                 _tmp_data = i
                 _tmp_data = _tmp_data.replace(
                     _peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                 _tmp_data = _tmp_data.replace(_dst_sub, BOGUS_SUB)
                 _tmp_data = _tmp_data.replace(_src_sub, _orig_dst)
                 _tmp_data = _tmp_data.replace(BOGUS_SUB, _orig_src)
                 _tmp_data = self.hashed_packet(
                     NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                 # Send the packet to all peers in the target IPSC
                 self.send_to_ipsc(_tmp_data)
                 time.sleep(0.06)
             self.CALL_DATA = []
Esempio n. 3
0
class playbackIPSC(IPSC):
    
    def __init__(self, *args, **kwargs):
        IPSC.__init__(self, *args, **kwargs)
        self.CALL_DATA = []
        
    #************************************************
    #     CALLBACK FUNCTIONS FOR USER PACKET TYPES
    #************************************************
    #
    if GROUP_REPEAT:
	logger.info('Playback: DEFINING GROUP REPEAT FUNCTION')
        def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
            if HEX_TGID == _dst_sub and _ts in GROUP_TS:
                if not _end:
                    if not self.CALL_DATA:
                        logger.info('(%s) Receiving transmission to be played back from subscriber: %s', _network, int_id(_src_sub))
                    _tmp_data = _data
                    #_tmp_data = dmr_nat(_data, _src_sub, NETWORK[_network]['LOCAL']['RADIO_ID'])
                    self.CALL_DATA.append(_tmp_data)
                if _end:
                    self.CALL_DATA.append(_data)
                    time.sleep(2)
                    logger.info('(%s) Playing back transmission from subscriber: %s', _network, int_id(_src_sub))
                    for i in self.CALL_DATA:
                        _tmp_data = i
                        _tmp_data = _tmp_data.replace(_peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                        _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                        # Send the packet to all peers in the target IPSC
                        self.send_to_ipsc(_tmp_data)
                        time.sleep(0.06)
                    self.CALL_DATA = []
                
    if PRIVATE_REPEAT:
	logger.info('Playback: DEFINING PRIVATE REPEAT FUNCTION')
        def private_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
            if HEX_SUB == _dst_sub and _ts in PRIVATE_TS:
                if not _end:
                    if not self.CALL_DATA:
                        logger.info('(%s) Receiving transmission to be played back from subscriber: %s, to subscriber: %s', _network, int_id(_src_sub), int_id(_dst_sub))
                    _tmp_data = _data
                    self.CALL_DATA.append(_tmp_data)
                if _end:
                    self.CALL_DATA.append(_data)
                    time.sleep(1)
                    logger.info('(%s) Playing back transmission from subscriber: %s, to subscriber %s', _network, int_id(_src_sub), int_id(_dst_sub))
                    _orig_src = _src_sub
                    _orig_dst = _dst_sub
                    for i in self.CALL_DATA:
                        _tmp_data = i
                        _tmp_data = _tmp_data.replace(_peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                        _tmp_data = _tmp_data.replace(_dst_sub, BOGUS_SUB)
                        _tmp_data = _tmp_data.replace(_src_sub, _orig_dst)
                        _tmp_data = _tmp_data.replace(BOGUS_SUB, _orig_src)
                        _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                        # Send the packet to all peers in the target IPSC
                        self.send_to_ipsc(_tmp_data)
                        time.sleep(0.06)
                    self.CALL_DATA = []
Esempio n. 4
0
    def __init__(self, *args, **kwargs):
        IPSC.__init__(self, *args, **kwargs)
        if BRIDGES:
            logger.info('Initializing backup/polite bridging')
            self.BRIDGE = False
        else:
            self.BRIDGE = True
            logger.info('Initializing standard bridging')

        self.IPSC_STATUS = {
            'TS1': {'RX_GROUP':'\x00', 'TX_GROUP':'\x00', 'RX_TIME':0, 'TX_TIME':0, 'RX_SRC_SUB':'\x00', 'TX_SRC_SUB':'\x00'},
            'TS2': {'RX_GROUP':'\x00', 'TX_GROUP':'\x00', 'RX_TIME':0, 'TX_TIME':0, 'RX_SRC_SUB':'\x00', 'TX_SRC_SUB':'\x00'}
        }
Esempio n. 5
0
    def __init__(self, *args, **kwargs):
        IPSC.__init__(self, *args, **kwargs)
        if BRIDGES:
            logger.info('Initializing backup/polite bridging')
            self.BRIDGE = False
        else:
            self.BRIDGE = True
            logger.info('Initializing standard bridging')

        self.IPSC_STATUS = {
            'TS1': {'RX_GROUP':'\x00', 'TX_GROUP':'\x00', 'RX_TIME':0, 'TX_TIME':0, 'RX_SRC_SUB':'\x00', 'TX_SRC_SUB':'\x00'},
            'TS2': {'RX_GROUP':'\x00', 'TX_GROUP':'\x00', 'RX_TIME':0, 'TX_TIME':0, 'RX_SRC_SUB':'\x00', 'TX_SRC_SUB':'\x00'}
        }
Esempio n. 6
0
 def bridge_presence_loop(self):
     _temp_bridge = True
     for peer in BRIDGES:
         _peer = hex_str_4(peer)
     
         if _peer in self._peers.keys() and (self._peers[_peer]['MODE_DECODE']['TS_1'] or self._peers[_peer]['MODE_DECODE']['TS_2']):
             _temp_bridge = False
             logger.debug('(%s) Peer %s is an active bridge', self._network, int_id(_peer))
     
         if _peer == self._master['RADIO_ID'] \
             and self._master['STATUS']['CONNECTED'] \
             and (self._master['MODE_DECODE']['TS_1'] or self._master['MODE_DECODE']['TS_2']):
             _temp_bridge = False
             logger.debug('(%s) Master %s is an active bridge',self._network, int_id(_peer))
     
     if self.BRIDGE != _temp_bridge:
         logger.info('(%s) Changing bridge status to: %s', self._network, _temp_bridge )
     self.BRIDGE = _temp_bridge
Esempio n. 7
0
 def bridge_presence_loop(self):
     _temp_bridge = True
     for peer in BRIDGES:
         _peer = hex_str_4(peer)
     
         if _peer in self._peers.keys() and (self._peers[_peer]['MODE_DECODE']['TS_1'] or self._peers[_peer]['MODE_DECODE']['TS_2']):
             _temp_bridge = False
             logger.debug('(%s) Peer %s is an active bridge', self._network, int_id(_peer))
     
         if _peer == self._master['RADIO_ID'] \
             and self._master['STATUS']['CONNECTED'] \
             and (self._master['MODE_DECODE']['TS_1'] or self._master['MODE_DECODE']['TS_2']):
             _temp_bridge = False
             logger.debug('(%s) Master %s is an active bridge',self._network, int_id(_peer))
     
     if self.BRIDGE != _temp_bridge:
         logger.info('(%s) Changing bridge status to: %s', self._network, _temp_bridge )
     self.BRIDGE = _temp_bridge
Esempio n. 8
0
 def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
     if HEX_TGID == _dst_sub and _ts in GROUP_TS:
         if not _end:
             if not self.CALL_DATA:
                 logger.info('(%s) Receiving transmission to be played back from subscriber: %s', _network, int_id(_src_sub))
             _tmp_data = _data
             #_tmp_data = dmr_nat(_data, _src_sub, NETWORK[_network]['LOCAL']['RADIO_ID'])
             self.CALL_DATA.append(_tmp_data)
         if _end:
             self.CALL_DATA.append(_data)
             time.sleep(2)
             logger.info('(%s) Playing back transmission from subscriber: %s', _network, int_id(_src_sub))
             for i in self.CALL_DATA:
                 _tmp_data = i
                 _tmp_data = _tmp_data.replace(_peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                 _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                 # Send the packet to all peers in the target IPSC
                 send_to_ipsc(_network, _tmp_data)
                 time.sleep(0.06)
             self.CALL_DATA = []
Esempio n. 9
0
 def private_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
     if HEX_SUB == _dst_sub and _ts in PRIVATE_TS:
         if not _end:
             if not self.CALL_DATA:
                 logger.info('(%s) Receiving transmission to be played back from subscriber: %s, to subscriber: %s', _network, int_id(_src_sub), int_id(_dst_sub))
             _tmp_data = _data
             self.CALL_DATA.append(_tmp_data)
         if _end:
             self.CALL_DATA.append(_data)
             time.sleep(1)
             logger.info('(%s) Playing back transmission from subscriber: %s, to subscriber %s', _network, int_id(_src_sub), int_id(_dst_sub))
             _orig_src = _src_sub
             _orig_dst = _dst_sub
             for i in self.CALL_DATA:
                 _tmp_data = i
                 _tmp_data = _tmp_data.replace(_peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                 _tmp_data = _tmp_data.replace(_dst_sub, BOGUS_SUB)
                 _tmp_data = _tmp_data.replace(_src_sub, _orig_dst)
                 _tmp_data = _tmp_data.replace(BOGUS_SUB, _orig_src)
                 _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                 # Send the packet to all peers in the target IPSC
                 send_to_ipsc(_network, _tmp_data)
                 time.sleep(0.06)
             self.CALL_DATA = []
Esempio n. 10
0
        _ambe_frame2 = _ambe_frames[50:99]
        _ambe_frame3 = _ambe_frames[100:149]

        if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
            print('Voice Transmission Start')
        if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
            print('Voice Transmission End')
        if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
            print(_ambe_frames)
            print('Frame 1:', _ambe_frame1.bytes)
            print('Frame 2:', _ambe_frame2.bytes)
            print('Frame 3:', _ambe_frame3.bytes)
        if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
            print(_ambe_frames)
            print('Frame 1:', _ambe_frame1.bytes)
            print('Frame 2:', _ambe_frame2.bytes)
            print('Frame 3:', _ambe_frame3.bytes)


if __name__ == '__main__':
    logger.info(
        'DMRlink \'ambe_audio.py\' (c) 2015 N0MJS & the K0USY Group - SYSTEM STARTING...'
    )
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = ambeIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'],
                              networks[ipsc_network],
                              interface=NETWORK[ipsc_network]['LOCAL']['IP'])
    reactor.run()
Esempio n. 11
0
 def __init__(self, *args, **kwargs):
     IPSC.__init__(self, *args, **kwargs)
     self.BRIDGE = False
     self.ACTIVE_CALLS = []
     logger.info('(%s) Initializing bridge status as: %s', self._network, self.BRIDGE)
Esempio n. 12
0
    'SLOT1_VOICE': '\x0A',
    'SLOT2_VOICE': '\x8A'   
}

# Notes and pieces of next steps...
# RPT_WAKE_UP = b'\x85' + NETWORK[_network]['LOCAL']['RADIO_ID] + b'\x00\x00\x00\x01' + b'\x01' + b'\x01'
# TS1 = 0, TS2 = 1

# Import Bridging rules
# Note: A stanza *must* exist for any IPSC configured in the main
# configuration file and listed as "active". It can be empty, 
# but it has to exist.
#
try:
    from bridge_rules import RULES
    logger.info('Bridge rules file found and rules imported')
except ImportError:
    sys.exit('Bridging rules file not found or invalid')

# Convert integer GROUP ID numbers from the config into hex strings
# we need to send in the actual data packets.
#

for _ipsc in RULES:
    for _rule in RULES[_ipsc]['GROUP_VOICE']:
        _rule['SRC_GROUP'] = hex_str_3(_rule['SRC_GROUP'])
        _rule['DST_GROUP'] = hex_str_3(_rule['DST_GROUP'])
        _rule['SRC_TS'] = _rule['SRC_TS'] - 1
        _rule['DST_TS'] = _rule['DST_TS'] - 1

Esempio n. 13
0
        _source   = int_id(_data[1:5])
        _ipsc_src = int_id(_data[5:9])
        _ts       = TS[_data[13]]
        _status   = _data[15] # suspect [14:16] but nothing in leading byte?
        _rf_src   = int_id(_data[16:19])
        _rf_tgt   = int_id(_data[19:22])
        _type     = _data[22]

        try:
            _status = STATUS[_status]
        except KeyError:
            pass
        try:
            _type = TYPE[_type]
        except KeyError:
            pass
            
        con = pymysql.connect(host = db_host, port = db_port, user = db_user, passwd = db_pwd, db = db_name)
        cur = con.cursor()
        cur.execute("insert INTO rcm_status(data_source, ipsc, timeslot, type, subscriber, talkgroup, status) VALUES(%s, %s, %s, %s, %s, %s, %s)", (_source, _ipsc_src, _ts, _type, _rf_src, _rf_tgt, _status))
        con.commit()
        con.close()


if __name__ == '__main__':
    logger.info('DMRlink \'rcm_db_log.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = rcmIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'], networks[ipsc_network], interface=NETWORK[ipsc_network]['LOCAL']['IP'])
    reactor.run()
Esempio n. 14
0
__license__ = 'Creative Commons Attribution-ShareAlike 3.0 Unported'
__maintainer__ = 'Cort Buffington, N0MJS'
__email__ = '*****@*****.**'
__status__ = 'beta'


try:
    from playback_config import *
except ImportError:
    sys.exit('Configuration file not found or invalid')

HEX_TGID    = hex_str_3(TGID)
HEX_SUB     = hex_str_3(SUB)
BOGUS_SUB   = '\xFF\xFF\xFF'
if GROUP_SRC_SUB:
    logger.info('Playback: USING SUBSCRIBER ID: %s FOR GROUP REPEAT', GROUP_SRC_SUB)
    HEX_GRP_SUB = hex_str_3(GROUP_SRC_SUB)

class playbackIPSC(IPSC):
    
    def __init__(self, *args, **kwargs):
        IPSC.__init__(self, *args, **kwargs)
        self.CALL_DATA = []
        
    #************************************************
    #     CALLBACK FUNCTIONS FOR USER PACKET TYPES
    #************************************************
    #
    if GROUP_REPEAT:
	logger.info('Playback: DEFINING GROUP REPEAT FUNCTION')
        def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
Esempio n. 15
0
    def group_voice(self, _network, _src_sub, _dst_group, _ts, _end, _peerid,
                    _data):
        if _end:
            _self_peer = NETWORK[_network]['LOCAL']['RADIO_ID']
            _self_src = _self_peer[1:]

            if (_peerid == _self_peer) or (_src_sub == _self_src):
                logger.error(
                    '(%s) Just received a packet that appears to have been originated by us. PeerID: %s Subscriber: %s TS: %s, TGID: %s',
                    _network, int_id(_peerid), int_id(_src_sub),
                    int(_ts) + 1, int_id(_dst_group))
                return

            if trigger == False:
                if (_ts == 0 and _dst_group not in trigger_groups_1) or (
                        _ts == 1 and _dst_group not in trigger_groups_2):
                    return
            else:
                if (_ts == 0 and _dst_group in trigger_groups_1) or (
                        _ts == 1 and _dst_group in trigger_groups_2):
                    return

            logger.info(
                '(%s) Event ID: %s - Playback triggered from SourceID: %s, TS: %s, TGID: %s, PeerID: %s',
                _network, self.event_id, int_id(_src_sub), _ts + 1,
                int_id(_dst_group), int_id(_peerid))

            # Determine the type of voice packet this is (see top of file for possible types)
            _burst_data_type = _data[30]

            time.sleep(2)
            self.CALL_DATA = pickle.load(open(filename, 'rb'))
            logger.info('(%s) Event ID: %s - Playing back file: %s', _network,
                        self.event_id, filename)

            for i in self.CALL_DATA:
                _tmp_data = i

                # re-Write the peer radio ID to that of this program
                _tmp_data = _tmp_data.replace(_peerid, _self_peer)
                # re-Write the source subscriber ID to that of this program
                _tmp_data = _tmp_data.replace(_src_sub, _self_src)
                # Re-Write the destination Group ID
                _tmp_data = _tmp_data.replace(_tmp_data[9:12], _dst_group)

                # Re-Write IPSC timeslot value
                _call_info = int_id(_tmp_data[17:18])
                if _ts == 0:
                    _call_info &= ~(1 << 5)
                elif _ts == 1:
                    _call_info |= 1 << 5
                _call_info = chr(_call_info)
                _tmp_data = _tmp_data[:17] + _call_info + _tmp_data[18:]

                # Re-Write DMR timeslot value
                # Determine if the slot is present, so we can translate if need be
                if _burst_data_type == BURST_DATA_TYPE[
                        'SLOT1_VOICE'] or _burst_data_type == BURST_DATA_TYPE[
                            'SLOT2_VOICE']:
                    # Re-Write timeslot if necessary...
                    if _ts == 0:
                        _burst_data_type = BURST_DATA_TYPE['SLOT1_VOICE']
                    elif _ts == 1:
                        _burst_data_type = BURST_DATA_TYPE['SLOT2_VOICE']
                    _tmp_data = _tmp_data[:30] + _burst_data_type + _tmp_data[
                        31:]

                _tmp_data = self.hashed_packet(
                    NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                # Send the packet to all peers in the target IPSC
                self.send_to_ipsc(_tmp_data)
                time.sleep(0.06)
            self.CALL_DATA = []
            logger.info('(%s) Event ID: %s - Playback Completed', _network,
                        self.event_id)
            self.event_id = self.event_id + 1
Esempio n. 16
0
    # echo "x,y,z" | nc 127.0.0.1 1235
    #
    def remote_control(self, port):
        s = socket.socket()  # Create a socket object
        host = socket.gethostname()  # Get local machine name
        s.bind((host, port))  # Bind to the port

        s.listen(5)  # Now wait for client connection.
        print("Remote control is listening on:", host, port)
        while True:
            c, addr = s.accept()  # Establish connection with client.
            print("Got connection from", addr)
            tgs = c.recv(1024)
            if tgs:
                self._tg_filter = map(int, tgs.split(","))
                print("New TGs=", self._tg_filter)
            c.close()  # Close the connection


if __name__ == "__main__":
    logger.info("DMRlink 'ambe_audio.py' (c) 2015 N0MJS & the K0USY Group - SYSTEM STARTING...")
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]["LOCAL"]["ENABLED"]:
            networks[ipsc_network] = ambeIPSC(ipsc_network)
            reactor.listenUDP(
                NETWORK[ipsc_network]["LOCAL"]["PORT"],
                networks[ipsc_network],
                interface=NETWORK[ipsc_network]["LOCAL"]["IP"],
            )
    reactor.run()
Esempio n. 17
0
                if not _end:
                    if not self.CALL_DATA:
                        logger.info('(%s) Receiving transmission to be played back from subscriber: %s, to subscriber: %s', _network, int_id(_src_sub), int_id(_dst_sub))
                    _tmp_data = _data
                    self.CALL_DATA.append(_tmp_data)
                if _end:
                    self.CALL_DATA.append(_data)
                    time.sleep(1)
                    logger.info('(%s) Playing back transmission from subscriber: %s, to subscriber %s', _network, int_id(_src_sub), int_id(_dst_sub))
                    _orig_src = _src_sub
                    _orig_dst = _dst_sub
                    for i in self.CALL_DATA:
                        _tmp_data = i
                        _tmp_data = _tmp_data.replace(_peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                        _tmp_data = _tmp_data.replace(_dst_sub, BOGUS_SUB)
                        _tmp_data = _tmp_data.replace(_src_sub, _orig_dst)
                        _tmp_data = _tmp_data.replace(BOGUS_SUB, _orig_src)
                        _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                        # Send the packet to all peers in the target IPSC
                        self.send_to_ipsc(_tmp_data)
                        time.sleep(0.06)
                    self.CALL_DATA = []
        
if __name__ == '__main__':
    logger.info('DMRlink \'playback.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = playbackIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'], networks[ipsc_network], interface=NETWORK[ipsc_network]['LOCAL']['IP'])
    reactor.run()
Esempio n. 18
0
    def group_voice(self, _network, _src_sub, _dst_group, _ts, _end, _peerid, _data):
        logger.debug('(%s) Group Voice Packet Received From: %s, IPSC Peer %s, Destination %s', _network, int_id(_src_sub), int_id(_peerid), int_id(_dst_group))
        _burst_data_type = _data[30] # Determine the type of voice packet this is (see top of file for possible types)
        if _ts == 0:
            _TS = 'TS1'
        elif _ts == 1:
            _TS = 'TS2'
        
        now = time()                                # Mark packet arrival time -- we'll need this for call contention handling 
        
        for rule in RULES[_network]['GROUP_VOICE']:
            _target = rule['DST_NET']               # Shorthand to reduce length and make it easier to read
            _status = networks[_target].IPSC_STATUS # Shorthand to reduce length and make it easier to read

            # Matching for rules is against the Destination Group in the SOURCE packet (SRC_GROUP)
            #if rule['SRC_GROUP'] == _dst_group and rule['SRC_TS'] == _ts:
            #if BRIDGES:
            if (rule['SRC_GROUP'] == _dst_group and rule['SRC_TS'] == _ts) and (self.BRIDGE == True or networks[_target].BRIDGE == True):
                if RULES[_network]['TRUNK'] == False:
                    if ((rule['DST_GROUP'] != _status[_TS]['RX_GROUP']) and ((now - _status[_TS]['RX_TIME']) < RULES[_network]['GROUP_HANGTIME'])):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged, target active or in group hangtime: IPSC %s, %s, TGID%s', _network, _target, _TS, int_id(rule['DST_GROUP']))
                        continue
                    
                    if ((rule['DST_GROUP'] != _status[_TS]['TX_GROUP']) and ((now - _status[_TS]['TX_TIME']) < RULES[_network]['GROUP_HANGTIME'])):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged to destination on TGID %s, target in group hangtime: IPSC %s, %s, TGID%s', _network, int_id(_status[_TS]['TX_GROUP']), _target, _TS, int_id(rule['DST_GROUP']))
                        continue

                    if (rule['DST_GROUP'] == _status[_TS]['TX_GROUP']) and (_src_sub != _status[_TS]['TX_SRC_SUB']) and ((now - _status[_TS]['TX_TIME']) < TS_CLEAR_TIME):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged, call bridge in progress from %s, target: IPSC %s, %s, TGID%s', _network, int_id(_src_sub), _target, _TS, int_id(rule['DST_GROUP']))
                        continue

                    if (rule['DST_GROUP'] == _status[_TS]['RX_GROUP']) and ((now - _status[_TS]['RX_TIME']) < TS_CLEAR_TIME):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged, matching call already active on target: IPSC %s, %s, TGID%s', _network, _target, _TS, int_id(rule['DST_GROUP']))
                        continue
                       
                _tmp_data = _data
                # Re-Write the IPSC SRC to match the target network's ID
                _tmp_data = _tmp_data.replace(_peerid, NETWORK[_target]['LOCAL']['RADIO_ID'])
                # Re-Write the destination Group ID
                _tmp_data = _tmp_data.replace(_dst_group, rule['DST_GROUP'])
            
                # Re-Write IPSC timeslot value
                _call_info = int_id(_data[17:18])
                if rule['DST_TS'] == 0:
                    _call_info &= ~(1 << 5)
                elif rule['DST_TS'] == 1:
                    _call_info |= 1 << 5
                _call_info = chr(_call_info)
                _tmp_data = _tmp_data[:17] + _call_info + _tmp_data[18:] 
                
                # Re-Write DMR timeslot value
                # Determine if the slot is present, so we can translate if need be
                if _burst_data_type == BURST_DATA_TYPE['SLOT1_VOICE'] or _burst_data_type == BURST_DATA_TYPE['SLOT2_VOICE']:
                    _slot_valid = True
                else:
                    _slot_valid = False
                # Re-Write timeslot if necessary...
                if _slot_valid:
                    if rule['DST_TS'] == 0:
                        _burst_data_type = BURST_DATA_TYPE['SLOT1_VOICE']
                    elif rule['DST_TS'] == 1:
                        _burst_data_type = BURST_DATA_TYPE['SLOT2_VOICE']
                    _tmp_data = _tmp_data[:30] + _burst_data_type + _tmp_data[31:]
            
                # Calculate and append the authentication hash for the target network... if necessary
                if NETWORK[_target]['LOCAL']['AUTH_ENABLED']:
                    _tmp_data = self.hashed_packet(NETWORK[_target]['LOCAL']['AUTH_KEY'], _tmp_data)
                # Send the packet to all peers in the target IPSC
                networks[_target].send_to_ipsc(_tmp_data)

                _status[_TS]['TX_GROUP'] = rule['DST_GROUP']
                _status[_TS]['TX_TIME'] = now
                _status[_TS]['TX_SRC_SUB'] = _src_sub

        # Mark the group and time that a packet was recieved
        self.IPSC_STATUS[_TS]['RX_GROUP'] = _dst_group
        self.IPSC_STATUS[_TS]['RX_TIME'] = now 
Esempio n. 19
0
    'SLOT1_VOICE': '\x0A',
    'SLOT2_VOICE': '\x8A'   
}

# Minimum time between different subscribers transmitting on the same TGID
#
TS_CLEAR_TIME = .2

# Import Bridging rules
# Note: A stanza *must* exist for any IPSC configured in the main
# configuration file and listed as "active". It can be empty, 
# but it has to exist.
#
try:
    from bridge_rules import RULES as RULES_FILE
    logger.info('Bridge rules file found and rules imported')
except ImportError:
    sys.exit('Bridging rules file not found or invalid')

# Convert integer GROUP ID numbers from the config into hex strings
# we need to send in the actual data packets.
#

for _ipsc in RULES_FILE:
    for _rule in RULES_FILE[_ipsc]['GROUP_VOICE']:
        _rule['SRC_GROUP'] = hex_str_3(_rule['SRC_GROUP'])
        _rule['DST_GROUP'] = hex_str_3(_rule['DST_GROUP'])
        _rule['SRC_TS']    = _rule['SRC_TS'] - 1
        _rule['DST_TS']    = _rule['DST_TS'] - 1
        for i, e in enumerate(_rule['ON']):
            _rule['ON'][i] = hex_str_3(_rule['ON'][i])
Esempio n. 20
0
    def group_voice(self, _network, _src_sub, _dst_group, _ts, _end, _peerid, _data):
        
        # Check for ACL match, and return if the subscriber is not allowed
        if allow_sub(_src_sub) == False:
            logger.warning('(%s) Group Voice Packet ***REJECTED BY ACL*** From: %s, IPSC Peer %s, Destination %s', _network, int_id(_src_sub), int_id(_peerid), int_id(_dst_group))
            return
        
        # Process the packet
        logger.debug('(%s) Group Voice Packet Received From: %s, IPSC Peer %s, Destination %s', _network, int_id(_src_sub), int_id(_peerid), int_id(_dst_group))
        _burst_data_type = _data[30] # Determine the type of voice packet this is (see top of file for possible types)
        if _ts == 0:
            _TS = 'TS1'
        elif _ts == 1:
            _TS = 'TS2'               
        
        now = time() # Mark packet arrival time -- we'll need this for call contention handling 
        
        for rule in RULES[_network]['GROUP_VOICE']:
            _target = rule['DST_NET']               # Shorthand to reduce length and make it easier to read
            _status = networks[_target].IPSC_STATUS # Shorthand to reduce length and make it easier to read

            # Matching for rules is against the Destination Group in the SOURCE packet (SRC_GROUP)
            # if rule['SRC_GROUP'] == _dst_group and rule['SRC_TS'] == _ts:
            # if BRIDGES:
            if (rule['SRC_GROUP'] == _dst_group and rule['SRC_TS'] == _ts and rule['ACTIVE'] == True) and (self.BRIDGE == True or networks[_target].BRIDGE == True):
                
                #
                # BEGIN CONTENTION HANDLING
                # 
                # If this is an inter-DMRlink trunk, this isn't necessary
                if RULES[_network]['TRUNK'] == False: 
                    
                    # The rules for each of the 4 "ifs" below are listed here for readability. The Frame To Send is:
                    #   From a different group than last RX from this IPSC, but it has been less than Group Hangtime
                    #   From a different group than last TX to this IPSC, but it has been less than Group Hangtime
                    #   From the same group as the last RX from this IPSC, but from a different subscriber, and it has been less than TS Clear Time
                    #   From the same group as the last TX to this IPSC, but from a different subscriber, and it has been less than TS Clear Time
                    # The "continue" at the end of each means the next iteration of the for loop that tests for matching rules
                    #
                    if ((rule['DST_GROUP'] != _status[_TS]['RX_GROUP']) and ((now - _status[_TS]['RX_TIME']) < RULES[_network]['GROUP_HANGTIME'])):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged, target active or in group hangtime: IPSC %s, %s, TGID%s', _network, _target, _TS, int_id(rule['DST_GROUP']))
                        continue    
                    if ((rule['DST_GROUP'] != _status[_TS]['TX_GROUP']) and ((now - _status[_TS]['TX_TIME']) < RULES[_network]['GROUP_HANGTIME'])):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged to destination on TGID %s, target in group hangtime: IPSC %s, %s, TGID%s', _network, int_id(_status[_TS]['TX_GROUP']), _target, _TS, int_id(rule['DST_GROUP']))
                        continue
                    if (rule['DST_GROUP'] == _status[_TS]['RX_GROUP']) and ((now - _status[_TS]['RX_TIME']) < TS_CLEAR_TIME):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged, matching call already active on target: IPSC %s, %s, TGID%s', _network, _target, _TS, int_id(rule['DST_GROUP']))
                        continue
                    if (rule['DST_GROUP'] == _status[_TS]['TX_GROUP']) and (_src_sub != _status[_TS]['TX_SRC_SUB']) and ((now - _status[_TS]['TX_TIME']) < TS_CLEAR_TIME):
                        if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                            logger.info('(%s) Call not bridged, call bridge in progress from %s, target: IPSC %s, %s, TGID%s', _network, int_id(_src_sub), _target, _TS, int_id(rule['DST_GROUP']))
                        continue
                #
                # END CONTENTION HANDLING
                #
                
                
                #
                # BEGIN FRAME FORWARDING
                #     
                # Make a copy of the payload       
                _tmp_data = _data
                
                # Re-Write the IPSC SRC to match the target network's ID
                _tmp_data = _tmp_data.replace(_peerid, NETWORK[_target]['LOCAL']['RADIO_ID'])
                
                # Re-Write the destination Group ID
                _tmp_data = _tmp_data.replace(_dst_group, rule['DST_GROUP'])
            
                # Re-Write IPSC timeslot value
                _call_info = int_id(_data[17:18])
                if rule['DST_TS'] == 0:
                    _call_info &= ~(1 << 5)
                elif rule['DST_TS'] == 1:
                    _call_info |= 1 << 5
                _call_info = chr(_call_info)
                _tmp_data = _tmp_data[:17] + _call_info + _tmp_data[18:] 
                
                # Re-Write DMR timeslot value
                # Determine if the slot is present, so we can translate if need be
                if _burst_data_type == BURST_DATA_TYPE['SLOT1_VOICE'] or _burst_data_type == BURST_DATA_TYPE['SLOT2_VOICE']:
                    _slot_valid = True
                else:
                    _slot_valid = False
                # Re-Write timeslot if necessary...
                if _slot_valid:
                    if rule['DST_TS'] == 0:
                        _burst_data_type = BURST_DATA_TYPE['SLOT1_VOICE']
                    elif rule['DST_TS'] == 1:
                        _burst_data_type = BURST_DATA_TYPE['SLOT2_VOICE']
                    _tmp_data = _tmp_data[:30] + _burst_data_type + _tmp_data[31:]
            
                # Calculate and append the authentication hash for the target network... if necessary
                if NETWORK[_target]['LOCAL']['AUTH_ENABLED']:
                    _tmp_data = self.auth_hashed_packet(NETWORK[_target]['LOCAL']['AUTH_KEY'], _tmp_data)
                # Send the packet to all peers in the target IPSC
                networks[_target].send_to_ipsc(_tmp_data)
                #
                # END FRAME FORWARDING
                #
                
                
                # Set values for the contention handler to test next time there is a frame to forward
                _status[_TS]['TX_GROUP'] = rule['DST_GROUP']
                _status[_TS]['TX_TIME'] = now
                _status[_TS]['TX_SRC_SUB'] = _src_sub
                

        # Mark the group and time that a packet was recieved for the contention handler to use later
        self.IPSC_STATUS[_TS]['RX_GROUP'] = _dst_group
        self.IPSC_STATUS[_TS]['RX_TIME']  = now
        
        
        #
        # BEGIN IN-BAND SIGNALING BASED ON TGID & VOICE TERMINATOR FRAME
        #
        # Activate/Deactivate rules based on group voice activity -- PTT or UA for you c-Bridge dorks.
        # This will ONLY work for symmetrical rules!!!
        
        # Action happens on un-key
        if _burst_data_type == BURST_DATA_TYPE['VOICE_TERM']:
            
            # Iterate the rules dictionary
            for rule in RULES[_network]['GROUP_VOICE']:
                
                # TGID matches an ACTIVATION trigger
                if _dst_group in rule['ON']:
                    # Set the matching rule as ACTIVE
                    rule['ACTIVE'] = True
                    logger.info('(%s) Primary Bridge Rule \"%s\" changed to state: %s', _network, rule['NAME'], rule['ACTIVE'])
                    
                    # Set reciprocal rules for other IPSCs as ACTIVE
                    _target = rule['DST_NET']
                    for target_rule in RULES[_target]['GROUP_VOICE']:
                        if target_rule['NAME'] == rule['NAME']:
                            target_rule['ACTIVE'] = True
                            logger.info('(%s) Reciprocal Bridge Rule \"%s\" in IPSC \"%s\" changed to state: %s', _network, target_rule['NAME'], _target, rule['ACTIVE'])
                            
                # TGID matches an DE-ACTIVATION trigger
                if _dst_group in rule['OFF']:
                    # Set the matching rule as ACTIVE
                    rule['ACTIVE'] = False
                    logger.info('(%s) Bridge Rule \"%s\" changed to state: %s', _network, rule['NAME'], rule['ACTIVE'])
                    
                    # Set reciprocal rules for other IPSCs as ACTIVE
                    _target = rule['DST_NET']
                    for target_rule in RULES[_target]['GROUP_VOICE']:
                        if target_rule['NAME'] == rule['NAME']:
                            target_rule['ACTIVE'] = False
                            logger.info('(%s) Reciprocal Bridge Rule \"%s\" in IPSC \"%s\" changed to state: %s', _network, target_rule['NAME'], _target, rule['ACTIVE'])
Esempio n. 21
0
BURST_DATA_TYPE = {
    'VOICE_HEAD':  '\x01',
    'VOICE_TERM':  '\x02',
    'SLOT1_VOICE': '\x0A',
    'SLOT2_VOICE': '\x8A'   
}
TS_CLEAR_TIME = .2

# Import Bridging rules
# Note: A stanza *must* exist for any IPSC configured in the main
# configuration file and listed as "active". It can be empty, 
# but it has to exist.
#
try:
    from bridge_rules import RULES as RULES_FILE
    logger.info('Bridge rules file found and rules imported')
except ImportError:
    sys.exit('Bridging rules file not found or invalid')

# Convert integer GROUP ID numbers from the config into hex strings
# we need to send in the actual data packets.
#

for _ipsc in RULES_FILE:
    for _rule in RULES_FILE[_ipsc]['GROUP_VOICE']:
        _rule['SRC_GROUP'] = hex_str_3(_rule['SRC_GROUP'])
        _rule['DST_GROUP'] = hex_str_3(_rule['DST_GROUP'])
        _rule['SRC_TS'] = _rule['SRC_TS'] - 1
        _rule['DST_TS'] = _rule['DST_TS'] - 1
    if _ipsc not in NETWORK:
        sys.exit('ERROR: Bridge rules found for an IPSC network not configured in main configuration')
Esempio n. 22
0
File: log.py Progetto: ebook/DMRlink
        _dst_sub    = get_info(int_id(_dst_sub), subscriber_ids)
        _peerid     = get_info(int_id(_peerid), peer_ids)
        _src_sub    = get_info(int_id(_src_sub), subscriber_ids)
        print('({}) Private Data Packet Received From: {} To: {}' .format(_network, _src_sub, _dst_sub))

class logUnauthIPSC(logIPSC):
    
    # There isn't a hash to build, so just return the data
    #
    def hashed_packet(self, _key, _data):
        return _data   
    
    # Remove the hash from a packet and return the payload... except don't
    #
    def strip_hash(self, _data):
        return _data
    
    # Everything is validated, so just return True
    #
    def validate_auth(self, _key, _data):
        return True
if __name__ == '__main__':
    logger.info('DMRlink \'log.py\' (c) 2013 N0MJS & the K0USY Group - SYSTEM STARTING...')
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            if NETWORK[ipsc_network]['LOCAL']['AUTH_ENABLED']:
                networks[ipsc_network] = logIPSC(ipsc_network)
            else:
                networks[ipsc_network] = logUnauthIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'], networks[ipsc_network])
    reactor.run()
Esempio n. 23
0
                if not _end:
                    if not self.CALL_DATA:
                        logger.info('(%s) Receiving transmission to be played back from subscriber: %s, to subscriber: %s', _network, int_id(_src_sub), int_id(_dst_sub))
                    _tmp_data = _data
                    self.CALL_DATA.append(_tmp_data)
                if _end:
                    self.CALL_DATA.append(_data)
                    time.sleep(1)
                    logger.info('(%s) Playing back transmission from subscriber: %s, to subscriber %s', _network, int_id(_src_sub), int_id(_dst_sub))
                    _orig_src = _src_sub
                    _orig_dst = _dst_sub
                    for i in self.CALL_DATA:
                        _tmp_data = i
                        _tmp_data = _tmp_data.replace(_peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                        _tmp_data = _tmp_data.replace(_dst_sub, BOGUS_SUB)
                        _tmp_data = _tmp_data.replace(_src_sub, _orig_dst)
                        _tmp_data = _tmp_data.replace(BOGUS_SUB, _orig_src)
                        _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                        # Send the packet to all peers in the target IPSC
                        send_to_ipsc(_network, _tmp_data)
                        time.sleep(0.06)
                    self.CALL_DATA = []
        
if __name__ == '__main__':
    logger.info('DMRlink \'playback.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = playbackIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'], networks[ipsc_network])
    reactor.run()
Esempio n. 24
0
                    # Re-Write timeslot if necessary...
                    if _ts == 0:
                        _burst_data_type = BURST_DATA_TYPE['SLOT1_VOICE']
                    elif _ts == 1:
                        _burst_data_type = BURST_DATA_TYPE['SLOT2_VOICE']
                    _tmp_data = _tmp_data[:30] + _burst_data_type + _tmp_data[
                        31:]

                _tmp_data = self.hashed_packet(
                    NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                # Send the packet to all peers in the target IPSC
                self.send_to_ipsc(_tmp_data)
                time.sleep(0.06)
            self.CALL_DATA = []
            logger.info('(%s) Event ID: %s - Playback Completed', _network,
                        self.event_id)
            self.event_id = self.event_id + 1


if __name__ == '__main__':
    logger.info(
        'DMRlink \'record.py\' (c) 2014 N0MJS & the K0USY Group - SYSTEM STARTING...'
    )
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = playIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'],
                              networks[ipsc_network],
                              interface=NETWORK[ipsc_network]['LOCAL']['IP'])
    reactor.run()
Esempio n. 25
0
 def group_voice(self, _network, _src_sub, _dst_group, _ts, _end, _peerid, _data):
     if _end:
         _self_peer = NETWORK[_network]['LOCAL']['RADIO_ID']
         _self_src = _self_peer[1:]
         
         if (_peerid == _self_peer) or (_src_sub == _self_src):
             logger.error('(%s) Just received a packet that appears to have been originated by us. PeerID: %s Subscriber: %s TS: %s, TGID: %s', _network, int_id(_peerid), int_id(_src_sub), int(_ts)+1, int_id(_dst_group))
             return
         
         if trigger == False:
             if (_ts == 0 and _dst_group not in trigger_groups_1) or (_ts == 1 and _dst_group not in trigger_groups_2):
                 return
         else:
             if (_ts == 0 and _dst_group in trigger_groups_1) or (_ts == 1 and _dst_group in trigger_groups_2):
                 return
         
         logger.info('(%s) Event ID: %s - Playback triggered from SourceID: %s, TS: %s, TGID: %s, PeerID: %s', _network, self.event_id, int_id(_src_sub), _ts+1, int_id(_dst_group), int_id(_peerid))
         
         # Determine the type of voice packet this is (see top of file for possible types)
         _burst_data_type = _data[30]
             
         time.sleep(2)
         self.CALL_DATA = pickle.load(open(filename, 'rb'))
         logger.info('(%s) Event ID: %s - Playing back file: %s', _network, self.event_id, filename)
        
         for i in self.CALL_DATA:
             _tmp_data = i
             
             # re-Write the peer radio ID to that of this program
             _tmp_data = _tmp_data.replace(_peerid, _self_peer)
             # re-Write the source subscriber ID to that of this program
             _tmp_data = _tmp_data.replace(_src_sub, _self_src)
             # Re-Write the destination Group ID
             _tmp_data = _tmp_data.replace(_tmp_data[9:12], _dst_group)
             
             # Re-Write IPSC timeslot value
             _call_info = int_id(_tmp_data[17:18])
             if _ts == 0:
                 _call_info &= ~(1 << 5)
             elif _ts == 1:
                 _call_info |= 1 << 5
             _call_info = chr(_call_info)
             _tmp_data = _tmp_data[:17] + _call_info + _tmp_data[18:]
                 
             # Re-Write DMR timeslot value
             # Determine if the slot is present, so we can translate if need be
             if _burst_data_type == BURST_DATA_TYPE['SLOT1_VOICE'] or _burst_data_type == BURST_DATA_TYPE['SLOT2_VOICE']:
                 # Re-Write timeslot if necessary...
                 if _ts == 0:
                     _burst_data_type = BURST_DATA_TYPE['SLOT1_VOICE']
                 elif _ts == 1:
                     _burst_data_type = BURST_DATA_TYPE['SLOT2_VOICE']
                 _tmp_data = _tmp_data[:30] + _burst_data_type + _tmp_data[31:]
             
             _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
             # Send the packet to all peers in the target IPSC
             self.send_to_ipsc(_tmp_data)
             time.sleep(0.06)
         self.CALL_DATA = []
         logger.info('(%s) Event ID: %s - Playback Completed', _network, self.event_id)
         self.event_id = self.event_id + 1
Esempio n. 26
0
BURST_DATA_TYPE = {
    'VOICE_HEAD':  '\x01',
    'VOICE_TERM':  '\x02',
    'SLOT1_VOICE': '\x0A',
    'SLOT2_VOICE': '\x8A'   
}
TS_CLEAR_TIME = .2

# Import Bridging rules
# Note: A stanza *must* exist for any IPSC configured in the main
# configuration file and listed as "active". It can be empty, 
# but it has to exist.
#
try:
    from bridge_rules import RULES as RULES_FILE
    logger.info('Bridge rules file found and rules imported')
except ImportError:
    sys.exit('Bridging rules file not found or invalid')

# Convert integer GROUP ID numbers from the config into hex strings
# we need to send in the actual data packets.
#

for _ipsc in RULES_FILE:
    for _rule in RULES_FILE[_ipsc]['GROUP_VOICE']:
        _rule['SRC_GROUP'] = hex_str_3(_rule['SRC_GROUP'])
        _rule['DST_GROUP'] = hex_str_3(_rule['DST_GROUP'])
        _rule['SRC_TS'] = _rule['SRC_TS'] - 1
        _rule['DST_TS'] = _rule['DST_TS'] - 1
    if _ipsc not in NETWORK:
        sys.exit('ERROR: Bridge rules found for an IPSC network not configured in main configuration')
Esempio n. 27
0
    def group_voice(self, _network, _src_sub, _dst_group, _ts, _end, _peerid, _data):
        logger.debug('(%s) Group Voice Packet Received From: %s, IPSC Peer %s, Destination %s', _network, int_id(_src_sub), int_id(_peerid), int_id(_dst_group))
        _burst_data_type = _data[30] # Determine the type of voice packet this is (see top of file for possible types)
        if _ts == 0:
            _TS = 'TS1'
        elif _ts == 1:
            _TS = 'TS2'
        
        now = time()                                # Mark packet arrival time -- we'll need this for call contention handling 
        
        for rule in RULES[_network]['GROUP_VOICE']:
            _target = rule['DST_NET']               # Shorthand to reduce length and make it easier to read
            _status = networks[_target].IPSC_STATUS # Shorthand to reduce length and make it easier to read

            # Matching for rules is against the Destination Group in the SOURCE packet (SRC_GROUP)
            #if rule['SRC_GROUP'] == _dst_group and rule['SRC_TS'] == _ts:
            #if BRIDGES:
            if (rule['SRC_GROUP'] == _dst_group and rule['SRC_TS'] == _ts) and (self.BRIDGE == True or networks[_target].BRIDGE == True):
                
                if ((rule['DST_GROUP'] != _status[_TS]['RX_GROUP']) and ((now - _status[_TS]['RX_TIME']) < RULES[_network]['GROUP_HANGTIME'])):
                    if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                        logger.info('(%s) Call not bridged, target active or in group hangtime: IPSC %s, %s, TGID%s', _network, _target, _TS, int_id(rule['DST_GROUP']))
                    return
                    
                if ((rule['DST_GROUP'] != _status[_TS]['TX_GROUP']) and ((now - _status[_TS]['TX_TIME']) < RULES[_network]['GROUP_HANGTIME'])):
                    if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                        logger.info('(%s) Call not bridged, target in group hangtime: IPSC %s, %s, TGID%s', _network, _target, _TS, int_id(rule['DST_GROUP']))
                    return

                if (rule['DST_GROUP'] == _status[_TS]['TX_GROUP']) and (_src_sub != _status[_TS]['TX_SRC_SUB']) and ((now - _status[_TS]['TX_TIME']) < TS_CLEAR_TIME):
                    if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                        logger.info('(%s) Call not bridged, call bridge in progress from %s, target: IPSC %s, %s, TGID%s', _network, int_id(_src_sub), _target, _TS, int_id(rule['DST_GROUP']))
                    return

                if (rule['DST_GROUP'] == _status[_TS]['RX_GROUP']) and ((now - _status[_TS]['RX_TIME']) < TS_CLEAR_TIME):
                    if _burst_data_type == BURST_DATA_TYPE['VOICE_HEAD']:
                        logger.info('(%s) Call not bridged, matching call already active on target: IPSC %s, %s, TGID%s', _network, _target, _TS, int_id(rule['DST_GROUP']))
                    return
                       
                _tmp_data = _data
                # Re-Write the IPSC SRC to match the target network's ID
                _tmp_data = _tmp_data.replace(_peerid, NETWORK[_target]['LOCAL']['RADIO_ID'])
                # Re-Write the destination Group ID
                _tmp_data = _tmp_data.replace(_dst_group, rule['DST_GROUP'])
            
                # Re-Write IPSC timeslot value
                _call_info = int_id(_data[17:18])
                if rule['DST_TS'] == 0:
                    _call_info &= ~(1 << 5)
                elif rule['DST_TS'] == 1:
                    _call_info |= 1 << 5
                _call_info = chr(_call_info)
                _tmp_data = _tmp_data[:17] + _call_info + _tmp_data[18:] 
                
                # Re-Write DMR timeslot value
                # Determine if the slot is present, so we can translate if need be
                if _burst_data_type == BURST_DATA_TYPE['SLOT1_VOICE'] or _burst_data_type == BURST_DATA_TYPE['SLOT2_VOICE']:
                    _slot_valid = True
                else:
                    _slot_valid = False
                # Re-Write timeslot if necessary...
                if _slot_valid:
                    if rule['DST_TS'] == 0:
                        _burst_data_type = BURST_DATA_TYPE['SLOT1_VOICE']
                    elif rule['DST_TS'] == 1:
                        _burst_data_type = BURST_DATA_TYPE['SLOT2_VOICE']
                    _tmp_data = _tmp_data[:30] + _burst_data_type + _tmp_data[31:]
            
                # Calculate and append the authentication hash for the target network... if necessary
                if NETWORK[_target]['LOCAL']['AUTH_ENABLED']:
                    _tmp_data = self.hashed_packet(NETWORK[_target]['LOCAL']['AUTH_KEY'], _tmp_data)
                # Send the packet to all peers in the target IPSC
                networks[_target].send_to_ipsc(_tmp_data)

                _status[_TS]['TX_GROUP'] = _dst_group
                _status[_TS]['TX_TIME'] = now
                _status[_TS]['TX_SRC_SUB'] = _src_sub

        # Mark the group and time that a packet was recieved
        self.IPSC_STATUS[_TS]['RX_GROUP'] = _dst_group
        self.IPSC_STATUS[_TS]['RX_TIME'] = now
Esempio n. 28
0
    
    def __init__(self, *args, **kwargs):
        IPSC.__init__(self, *args, **kwargs)
        self.CALL_DATA = []
        
    #************************************************
    #     CALLBACK FUNCTIONS FOR USER PACKET TYPES
    #************************************************
    #
    def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
        if _end:
            if True:
                time.sleep(2)
                self.CALL_DATA = pickle.load(open(filename, 'rb'))
                for i in self.CALL_DATA:
                    _tmp_data = i
                    _tmp_data = _tmp_data.replace(_peerid, NETWORK[_network]['LOCAL']['RADIO_ID'])
                    _tmp_data = self.hashed_packet(NETWORK[_network]['LOCAL']['AUTH_KEY'], _tmp_data)
                    # Send the packet to all peers in the target IPSC
                    self.send_to_ipsc(_tmp_data)
                    time.sleep(0.06)
                self.CALL_DATA = []
        
if __name__ == '__main__':
    logger.info('DMRlink \'record.py\' (c) 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = playIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'], networks[ipsc_network], interface=NETWORK[ipsc_network]['LOCAL']['IP'])
    reactor.run()
Esempio n. 29
0
        _payload_type = _data[30:31]
        # _ambe_frames = _data[33:52]
        _ambe_frames = BitArray('0x'+h(_data[33:52]))
        _ambe_frame1 = _ambe_frames[0:49]
        _ambe_frame2 = _ambe_frames[50:99]
        _ambe_frame3 = _ambe_frames[100:149]
        
        if _payload_type == BURST_DATA_TYPE['VOICE_HEAD']:
            print('Voice Transmission Start')
        if _payload_type == BURST_DATA_TYPE['VOICE_TERM']:
            print('Voice Transmission End')
        if _payload_type == BURST_DATA_TYPE['SLOT1_VOICE']:
            print(_ambe_frames)
            print('Frame 1:', _ambe_frame1.bytes)
            print('Frame 2:', _ambe_frame2.bytes)
            print('Frame 3:', _ambe_frame3.bytes)
        if _payload_type == BURST_DATA_TYPE['SLOT2_VOICE']:
            print(_ambe_frames)
            print('Frame 1:', _ambe_frame1.bytes)
            print('Frame 2:', _ambe_frame2.bytes)
            print('Frame 3:', _ambe_frame3.bytes)

        
if __name__ == '__main__':
    logger.info('DMRlink \'ambe_audio.py\' (c) 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = ambeIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'], networks[ipsc_network], interface=NETWORK[ipsc_network]['LOCAL']['IP'])
    reactor.run()
Esempio n. 30
0
        except KeyError:
            pass
        try:
            _type = TYPE[_type]
        except KeyError:
            pass

        con = pymysql.connect(host=db_host,
                              port=db_port,
                              user=db_user,
                              passwd=db_pwd,
                              db=db_name)
        cur = con.cursor()
        cur.execute(
            "insert INTO rcm_status(data_source, ipsc, timeslot, type, subscriber, talkgroup, status) VALUES(%s, %s, %s, %s, %s, %s, %s)",
            (_source, _ipsc_src, _ts, _type, _rf_src, _rf_tgt, _status))
        con.commit()
        con.close()


if __name__ == '__main__':
    logger.info(
        'DMRlink \'rcm_db_log.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...'
    )
    for ipsc_network in NETWORK:
        if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
            networks[ipsc_network] = rcmIPSC(ipsc_network)
            reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'],
                              networks[ipsc_network],
                              interface=NETWORK[ipsc_network]['LOCAL']['IP'])
    reactor.run()
Esempio n. 31
0
__credits__ = 'Adam Fast, KC0YLK; Dave Kierzkowski, KD8EYF'
__license__ = 'Creative Commons Attribution-ShareAlike 3.0 Unported'
__maintainer__ = 'Cort Buffington, N0MJS'
__email__ = '*****@*****.**'
__status__ = 'beta'

try:
    from playback_config import *
except ImportError:
    sys.exit('Configuration file not found or invalid')

HEX_TGID = hex_str_3(TGID)
HEX_SUB = hex_str_3(SUB)
BOGUS_SUB = '\xFF\xFF\xFF'
if GROUP_SRC_SUB:
    logger.info('Playback: USING SUBSCRIBER ID: %s FOR GROUP REPEAT',
                GROUP_SRC_SUB)
    HEX_GRP_SUB = hex_str_3(GROUP_SRC_SUB)


class playbackIPSC(IPSC):
    def __init__(self, *args, **kwargs):
        IPSC.__init__(self, *args, **kwargs)
        self.CALL_DATA = []

    #************************************************
    #     CALLBACK FUNCTIONS FOR USER PACKET TYPES
    #************************************************
    #
    if GROUP_REPEAT:
        logger.info('Playback: DEFINING GROUP REPEAT FUNCTION')