BEGIN working on bridge code

Stopped with this not completed, but mostly there. Need to fix some
references.
This commit is contained in:
Cort Buffington 2013-08-08 21:48:28 -05:00
parent 365f752c8e
commit 1dc2dc0081
2 changed files with 59 additions and 23 deletions

79
ipsc.py
View File

@ -105,6 +105,23 @@ def validate_auth(_key, _data):
_log(' AUTH: Invalid - Payload: %s, Hash: %s', binascii.b2a_hex(_payload), binascii.b2a_hex(_hash))
return False
# Forward Group Voice Packet
# THIS IS BROKEN - BEGIN WORK HERE. REPLACING SEGMENTS ISN'T REFERENCING THE RIGHT SUBSTITUTE DATA AND
# I'M GOIGN TO BED NOW.
def fwd_group_voice(_network, _data):
_src_group = _data[9:12]
_src_ipsc = _data[1:5]
for source in NETWORK[_network]['GROUP_VOICE']:
print(binascii.b2a_hex(_src_group), ' ', binascii.b2a_hex(source['SRC_GROUP']))
if source['SRC_GROUP'] == _src_group:
_data.replace(_src_ipsc, NETWORK[source]['DST_NET']['LOCAL']['RADIO_ID'])
_data.replace(_src_group, source['DST_GROUP'])
_data = hashed_packet(NETWORK[source]['DST_NET']['LOCAL']['AUTH_KEY'], _data)
print(binascii.b2a_hex(_data))
# Match source group to a rule
# Write destination group to packet
# Hash packet
# Send packet
# Take a recieved peer list and the network it belongs to, process and populate the
# data structure in my_ipsc_config with the results.
@ -238,7 +255,12 @@ class IPSC(DatagramProtocol):
#
self._peers = self._config['PEERS']
#
# This is a regular list to store peers for the IPSC. At times, parsing a simple list is much less
# Spendy than iterating a list of dictionaries... Maybe I'll find a better way in the future. Also
# We have to know when we have a new peer list, so a variable to indicate we do (or don't)
#
self._peer_list = []
self._peer_list_new = False
args = ()
@ -252,7 +274,7 @@ class IPSC(DatagramProtocol):
self.PEER_REG_REPLY_PKT = (PEER_REG_REPLY + self._local_id + IPSC_VER)
self.PEER_ALIVE_REQ_PKT = (PEER_ALIVE_REQ + self._local_id + self.TS_FLAGS)
self.PEER_ALIVE_REPLY_PKT = (PEER_ALIVE_REPLY + self._local_id + self.TS_FLAGS)
self._peer_list_new = False
else:
# If we didn't get called correctly, log it!
#
@ -278,20 +300,15 @@ class IPSC(DatagramProtocol):
# TIMED LOOP - MY CONNECTION MAINTENANCE
#************************************************
def timed_loop(self):
logger.debug('timed loop started') # temporary debugging to make sure this part runs
def timed_loop(self):
print_peer_list(self._network)
_master_connected = self._master_stat['CONNECTED']
_peer_list_rx = self._master_stat['PEER-LIST']
if (_master_connected == False):
if (self._master_stat['CONNECTED'] == False):
reg_packet = hashed_packet(self._local['AUTH_KEY'], self.MASTER_REG_REQ_PKT)
self.transport.write(reg_packet, (self._master_sock))
logger.debug('->> (%s) Master Registration Request To:%s From:%s', self._network, self._master_sock, binascii.b2a_hex(self._local_id))
elif (_master_connected == True):
elif (self._master_stat['CONNECTED'] == True):
master_alive_packet = hashed_packet(self._local['AUTH_KEY'], self.MASTER_ALIVE_PKT)
self.transport.write(master_alive_packet, (self._master_sock))
logger.debug('->> (%s) Master Keep-alive %s Sent To:%s', self._network, self._master_stat['KEEP_ALIVES_SENT'], self._master_sock)
@ -309,12 +326,12 @@ class IPSC(DatagramProtocol):
else:
logger.error('->> (%s) Master in UNKOWN STATE:%s:%s', self._network, self._master_sock)
if ((_master_connected == True) and (_peer_list_rx == False)):
if ((self._master_stat['CONNECTED'] == True) and (self._master_stat['PEER-LIST'] == False)):
peer_list_req_packet = hashed_packet(self._local['AUTH_KEY'], self.PEER_LIST_REQ_PKT)
self.transport.write(peer_list_req_packet, (self._master_sock))
logger.debug('->> (%s) List Reqested from Master:%s', self._network, self._master_sock)
if (_peer_list_rx == True):
if (self._master_stat['PEER-LIST'] == True):
for peer in (self._peers):
if (peer['RADIO_ID'] == self._local_id): # We are in the peer-list, but don't need to talk to ourselves
continue
@ -332,8 +349,8 @@ class IPSC(DatagramProtocol):
if peer['STATUS']['KEEP_ALIVES_OUTSTANDING'] >= self._local['MAX_MISSED']:
peer['STATUS']['CONNECTED'] = False
self._peer_list.remove(peer['RADIO_ID'])
self._peers.remove(peer)
self._peer_list.remove(peer['RADIO_ID']) # Remove the peer from the simple list FIRST
self._peers.remove(peer) # Becuase once it's out of the dictionary, you can't use it for anything else.
logger.error('Maximum Peer Keep-Alives Missed -- De-registering the Peer: %s', peer)
peer['STATUS']['KEEP_ALIVES_SENT'] += 1
@ -347,8 +364,7 @@ class IPSC(DatagramProtocol):
# RECEIVED DATAGRAM - ACT IMMEDIATELY!!!
#************************************************
# Work in progress -- at the very least, notify we have the packet. Ultimately
# call a function or process immediately if only a few actions
# Actions for recieved packets by type: Call a function or process here...
#
def datagramReceived(self, data, (host, port)):
logger.debug('received %r from %s:%d', binascii.b2a_hex(data), host, port)
@ -357,17 +373,26 @@ class IPSC(DatagramProtocol):
_peerid = data[1:5]
_dec_peerid = int(binascii.b2a_hex(_peerid), 16)
# First action: if Authentication is active, authenticate the packet
#
if bool(self._local['AUTH_KEY']) == True:
if validate_auth(self._local['AUTH_KEY'], data) == False:
logger.warning('(%s) AuthError: IPSC packet failed authentication. Type %s: Peer ID: %s', self._network, binascii.b2a_hex(_packettype), _dec_peerid)
return
data = strip_hash(data)
# Packets generated by "users" that are the most common should come first for efficiency.
#
if (_packettype == GROUP_VOICE):
if not(valid_master(self._network, _peerid) == False or valid_peer(self._peer_list, _peerid) == False):
logger.warning('(%s) PeerError: Peer not in peer-list: %s', self._network, _dec_peerid)
return
fwd_group_voice(self._network, data)
logger.debug('<<- (%s) Group Voice Packet From:%s:%s', self._network, host, port)
# IPSC keep alives, master and peer, come next in processing priority
#
elif (_packettype == PEER_ALIVE_REQ):
if valid_peer(self._peer_list, _peerid) == False:
@ -392,7 +417,10 @@ class IPSC(DatagramProtocol):
for peer in self._config['PEERS']:
if peer['RADIO_ID'] == _peerid:
peer['STATUS']['KEEP_ALIVES_OUTSTANDING'] = 0
# Registration requests and replies are infrequent, but important. Peer lists can go here too as a part
# of the registration process.
#
elif (_packettype == MASTER_REG_REQ):
logger.debug('<<- (%s) Master Registration Packet Recieved', self._network)
@ -414,13 +442,12 @@ class IPSC(DatagramProtocol):
if peer['RADIO_ID'] == _peerid:
peer['STATUS']['CONNECTED'] = True
elif (_packettype == XCMP_XNL):
logger.debug('<<- (%s) XCMP_XNL From:%s:%s, but we did not indicate XCMP capable!', self._network, host, port)
elif (_packettype == PEER_LIST_REPLY):
logger.debug('<<- (%s) Peer List Received From:%s:%s', self._network, host, port)
self._peer_list = process_peer_list(data, self._network, self._peer_list)
# Other "user" related packet types that we don't do much or anything with yet
#
elif (_packettype == PVT_VOICE):
logger.debug('<<- (%s) Voice Packet From:%s:%s', self._network, host, port)
@ -430,18 +457,24 @@ class IPSC(DatagramProtocol):
elif (_packettype == PVT_DATA):
logger.debug('<<- (%s) Private Data Packet From From:%s:%s', self._network, host, port)
elif (_packettype == RPT_WAKE_UP):
logger.debug('<<- (%s) Repeater Wake-Up Packet From:%s:%s', self._network, host, port)
elif (_packettype == DE_REG_REQ):
logger.debug('<<- (%s) Peer De-Registration Request From:%s:%s', self._network, host, port)
elif (_packettype == DE_REG_REPLY):
logger.debug('<<- (%s) Peer De-Registration Reply From:%s:%s', self._network, host, port)
elif (_packettype == RPT_WAKE_UP):
logger.debug('<<- (%s) Repeater Wake-Up Packet From:%s:%s', self._network, host, port)
# Technically, we're not paying any attention to these types because we're not part of the XCMP call control structure
#
elif (_packettype == XCMP_XNL):
logger.debug('<<- (%s) XCMP_XNL From:%s:%s, but we did not indicate XCMP capable!', self._network, host, port)
elif (_packettype in (CALL_CTL_1, CALL_CTL_2, CALL_CTL_3)):
logger.debug('<<- (%s) Call Control Packet From:%s:%s', self._network, host, port)
# If there's a packet type we don't know aobut, it should be logged so we can figure it out and take an appropriate action!
else:
packet_type = binascii.b2a_hex(_packettype)
logger.error('<<- (%s) Received Unprocessed Type %s From:%s:%s', self._network, packet_type, host, port)

View File

@ -9,6 +9,9 @@
# Configuration file for IPSC.py -- each network has several parts, some of this is muted by the script once it runs, thus there are placeholders
NETWORK = {
'IPSC1': {
'GROUP_VOICE': [
{'SRC_GROUP': b'\x00\x00\x01', 'DST_NET': 'IPSC2', 'DST_GROUP': b'\x00\x00\x02'}
],
'LOCAL': {
'MODE': b'\x6A', # Decoded values below
'PEER_OPER': True,