Continued Clean-Up More Efficient

more of the same stuff… organizing and cleaning up stuff to make it run
better. CPU load now reduced by half!
This commit is contained in:
Cort Buffington 2013-10-22 11:21:32 -05:00
parent f23780901b
commit 43c70bbdb1
2 changed files with 81 additions and 106 deletions

175
ipsc.py
View File

@ -48,12 +48,12 @@ except ImportError:
sys.exit('IPSC mask values file not found or invalid') sys.exit('IPSC mask values file not found or invalid')
ids = [] ids = {}
try: try:
with open('./radioids.csv', 'r') as radioids_csv: with open('./radioids.csv', 'r') as radioids_csv:
radio_ids = csv.reader(radioids_csv, dialect='excel', delimiter=',') radio_ids = csv.reader(radioids_csv, dialect='excel', delimiter=',')
for row in radio_ids: for row in radio_ids:
ids.append(row) ids[int(row[1])] = (row[0])
except ImportError: except ImportError:
sys.exit('No Radio ID CSV file found') sys.exit('No Radio ID CSV file found')
@ -167,42 +167,22 @@ def call_ctl_3(_network, _data):
def xcmp_xnl(_network, _data): def xcmp_xnl(_network, _data):
print('({}) XCMP/XNL Packet Received From: {}' .format(_network, _src_sub)) print('({}) XCMP/XNL Packet Received From: {}' .format(_network, _src_sub))
def group_voice(_network, _src_sub, _dst_group, _call, _peerid, _data): def group_voice(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
# _log = logger.debug # _log = logger.debug
if ((_network, _ts) not in ACTIVE_CALLS) or _end:
if _call == '\x00':
if (_network, 'Slot 1') not in ACTIVE_CALLS:
_time = time.strftime('%m/%d/%y %H:%M:%S')
_dst_group = get_info(int(binascii.b2a_hex(_dst_group), 16))
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16))
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16))
ACTIVE_CALLS.append((_network, 'Slot 1'))
print('{} ({}) CALL START Group Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t1' .format(_time, _network, _peerid, _src_sub, _dst_group))
if _call == '\x20':
if (_network, 'Slot 2') not in ACTIVE_CALLS:
_time = time.strftime('%m/%d/%y %H:%M:%S')
_dst_group = get_info(int(binascii.b2a_hex(_dst_group), 16))
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16))
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16))
ACTIVE_CALLS.append((_network, 'Slot 2'))
print('{} ({}) CALL START Group Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t2' .format(_time, _network, _peerid, _src_sub, _dst_group))
if _call == '\x40':
_time = time.strftime('%m/%d/%y %H:%M:%S') _time = time.strftime('%m/%d/%y %H:%M:%S')
_dst_group = get_info(int(binascii.b2a_hex(_dst_group), 16)) _dst_sub = get_info(int_id(_dst_sub))
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16)) _peerid = get_info(int_id(_peerid))
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16)) _src_sub = get_info(int_id(_src_sub))
ACTIVE_CALLS.remove((_network, 'Slot 1')) if not _end: ACTIVE_CALLS.append((_network, _ts))
print('{} ({}) CALL END Group Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t1 \a' .format(_time, _network, _peerid, _src_sub, _dst_group)) if _end: ACTIVE_CALLS.remove((_network, _ts))
if _call == '\x60': if _ts: _ts = 2
_time = time.strftime('%m/%d/%y %H:%M:%S') else: _ts = 1
_dst_group = get_info(int(binascii.b2a_hex(_dst_group), 16)) if _end: _end = 'END'
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16)) else: _end = 'START'
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16))
ACTIVE_CALLS.remove((_network, 'Slot 2')) print('{} ({}) Call {} Group Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t{}' .format(_time, _network, _end, _peerid, _src_sub, _dst_sub, _ts))
print('{} ({}) CALL END Group Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t2 \a' .format(_time, _network, _peerid, _src_sub, _dst_group))
''' '''
for source in NETWORK[_network]['RULES']['GROUP_VOICE']: for source in NETWORK[_network]['RULES']['GROUP_VOICE']:
@ -221,63 +201,41 @@ def group_voice(_network, _src_sub, _dst_group, _call, _peerid, _data):
send_to_ipsc(_target, _data) send_to_ipsc(_target, _data)
''' '''
def private_voice(_network, _src_sub, _dst_sub, _call, _peerid, _data): def private_voice(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
# _log = logger.debug # _log = logger.debug
if ((_network, _ts) not in ACTIVE_CALLS) or _end:
if _call == '\x00':
if (_network, 'Slot 1') not in ACTIVE_CALLS:
_time = time.strftime('%m/%d/%y %H:%M:%S')
_dst_sub = get_info(int(binascii.b2a_hex(_dst_sub), 16))
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16))
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16))
ACTIVE_CALLS.append((_network, 'Slot 1'))
print('{} ({}) CALL START Private Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t1' .format(_time, _network, _peerid, _src_sub, _dst_sub))
if _call == '\x20':
if (_network, 'Slot 2') not in ACTIVE_CALLS:
_time = time.strftime('%m/%d/%y %H:%M:%S')
_dst_sub = get_info(int(binascii.b2a_hex(_dst_sub), 16))
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16))
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16))
ACTIVE_CALLS.append((_network, 'Slot 2'))
print('({} {}) CALL START Private Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t2' .format(_time, _network, _peerid, _src_sub, _dst_sub))
if _call == '\x40':
_time = time.strftime('%m/%d/%y %H:%M:%S') _time = time.strftime('%m/%d/%y %H:%M:%S')
_dst_sub = get_info(int(binascii.b2a_hex(_dst_sub), 16)) _dst_sub = get_info(int_id(_dst_sub))
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16)) _peerid = get_info(int_id(_peerid))
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16)) _src_sub = get_info(int_id(_src_sub))
ACTIVE_CALLS.remove((_network, 'Slot 1')) if not _end: ACTIVE_CALLS.append((_network, _ts))
print('{} ({}) CALL END Private Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t1 \a' .format(_time, _network, _peerid, _src_sub, _dst_sub)) if _end: ACTIVE_CALLS.remove((_network, _ts))
if _call == '\x60': if _ts: _ts = 2
_time = time.strftime('%m/%d/%y %H:%M:%S') else: _ts = 1
_dst_sub = get_info(int(binascii.b2a_hex(_dst_sub), 16)) if _end: _end = 'END'
_peerid = get_info(int(binascii.b2a_hex(_peerid), 16)) else: _end = 'START'
_src_sub = get_info(int(binascii.b2a_hex(_src_sub), 16))
ACTIVE_CALLS.remove((_network, 'Slot 2')) print('{} ({}) Call {} Private Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t{}' .format(_time, _network, _end, _peerid, _src_sub, _dst_sub, _ts))
print('{} ({}) CALL END Private Voice: \n\tIPSC Source:\t{}\n\tSubscriber:\t{}\n\tDestination:\t{}\n\tTimeslot\t2 \a' .format(_time, _network, _peerid, _src_sub, _dst_sub))
def group_data(_network, _src_sub, _dst_sub, _call, _peerid, _data): def group_data(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
_dst_sub = get_info(int_id(_dst_sub))
_dst_sub = get_info(_dst_sub) _peerid = get_info(int_id(_peerid))
_peerid = get_info(_peerid) _src_sub = get_info(int_id(_src_sub))
_src_sub = get_info(_src_sub)
print('({}) Group Data Packet Received From: {}' .format(_network, _src_sub)) print('({}) Group Data Packet Received From: {}' .format(_network, _src_sub))
def private_data(__network, _src_sub, _dst_sub, _call, _peerid, _data): def private_data(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
_dst_sub = get_info(int_id(_dst_sub))
_dst_sub = get_info(_dst_sub) _peerid = get_info(int_id(_peerid))
_peerid = get_info(_peerid) _src_sub = get_info(int_id(_src_sub))
_src_sub = get_info(_src_sub)
print('({}) Private Data Packet Received From: {} To: {}' .format(_network, _src_sub, _dst_sub)) print('({}) Private Data Packet Received From: {} To: {}' .format(_network, _src_sub, _dst_sub))
def unknown_message(_network, _packettype, _data): def unknown_message(_network, _packettype, _peerid, _data):
_peerid = binascii.b2a_hex(_data[1:5]) _time = time.strftime('%m/%d/%y %H:%M:%S')
_packettype = binascii.b2a_hex(_packettype) _packettype = binascii.b2a_hex(_packettype)
_peerid = get_info(_peerid) _peerid = get_info(int_id(_peerid))
print("({}) Unknown message type encountered, Packet Type: {} From: {} " .format(_network, _packettype, _peerid)) print('{} ({}) Unknown message type encountered\n\tPacket Type: {}\n\tFrom: {}' .format(_time, _network, _packettype, _peerid))
print(binascii.b2a_hex(_data)) print('\t', binascii.b2a_hex(_data))
@ -285,6 +243,11 @@ def unknown_message(_network, _packettype, _data):
# UTILITY FUNCTIONS FOR INTERNAL USE # UTILITY FUNCTIONS FOR INTERNAL USE
#************************************************ #************************************************
# Convert a hex string to an int (radio ID, etc.)
#
def int_id(_hex_string):
return int(binascii.b2a_hex(_hex_string), 16)
# Re-Write Source Radio-ID (DMR NAT) # Re-Write Source Radio-ID (DMR NAT)
# #
def dmr_nat(_data, _nat_id): def dmr_nat(_data, _nat_id):
@ -297,9 +260,8 @@ def dmr_nat(_data, _nat_id):
# Lookup text data for numeric IDs # Lookup text data for numeric IDs
# #
def get_info(_id): def get_info(_id):
for id in ids: if _id in ids:
if int(id[1]) == _id: return ids[_id]
return id[0]
return _id return _id
# Remove the hash from a packet and return the payload # Remove the hash from a packet and return the payload
@ -654,7 +616,7 @@ class IPSC(DatagramProtocol):
The dict will typically contain a peer_id so the origin of the event is known. The dict will typically contain a peer_id so the origin of the event is known.
""" """
pass pass
return
#************************************************ #************************************************
# RECEIVED DATAGRAM - ACT IMMEDIATELY!!! # RECEIVED DATAGRAM - ACT IMMEDIATELY!!!
@ -670,11 +632,10 @@ class IPSC(DatagramProtocol):
def datagramReceived(self, data, (host, port)): def datagramReceived(self, data, (host, port)):
_packettype = data[0:1] _packettype = data[0:1]
_peerid = data[1:5] _peerid = data[1:5]
_dec_peerid = int(binascii.b2a_hex(_peerid), 16)
# Authenticate the packet # Authenticate the packet
if self.validate_auth(self._local['AUTH_KEY'], data) == False: if self.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) logger.warning('(%s) AuthError: IPSC packet failed authentication. Type %s: Peer ID: %s', self._network, binascii.b2a_hex(_packettype), int(binascii.b2a_hex(_peerid), 16))
return return
# Strip the hash, we won't need it anymore # Strip the hash, we won't need it anymore
@ -683,7 +644,7 @@ class IPSC(DatagramProtocol):
# Packets types that must be originated from a peer (including master peer) # Packets types that must be originated from a peer (including master peer)
if (_packettype in ANY_PEER_REQUIRED): if (_packettype in ANY_PEER_REQUIRED):
if not(valid_master(self._network, _peerid) == False or valid_peer(self._peer_list, _peerid) == False): 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) logger.warning('(%s) PeerError: Peer not in peer-list: %s', self._network, int(binascii.b2a_hex(_peerid), 16))
return return
# User, as in "subscriber" generated packets - a.k.a someone trasmitted # User, as in "subscriber" generated packets - a.k.a someone trasmitted
@ -691,27 +652,29 @@ class IPSC(DatagramProtocol):
# Extract commonly used items from the packet header # Extract commonly used items from the packet header
_src_sub = data[6:9] _src_sub = data[6:9]
_dst_sub = data[9:12] _dst_sub = data[9:12]
_call = data[17:18] _call = int_id(data[17:18])
_ts = bool(_call & TS_CALL_MSK)
_end = bool(_call & END_MSK)
# User Voice and Data Call Types: # User Voice and Data Call Types:
if (_packettype == GROUP_VOICE): if (_packettype == GROUP_VOICE):
self._notify_event(self._network, 'group_voice', {'peer_id': _dec_peerid}) self._notify_event(self._network, 'group_voice', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
group_voice(self._network, _src_sub, _dst_sub, _call, _peerid, data) group_voice(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
return return
elif (_packettype == PVT_VOICE): elif (_packettype == PVT_VOICE):
self._notify_event(self._network, 'private_voice', {'peer_id': _dec_peerid}) self._notify_event(self._network, 'private_voice', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
private_voice(self._network, _src_sub, _dst_sub, _call, _peerid, data) private_voice(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
return return
elif (_packettype == GROUP_DATA): elif (_packettype == GROUP_DATA):
self._notify_event(self._network, 'group_data', {'peer_id': _dec_peerid}) self._notify_event(self._network, 'group_data', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
group_data(self._network, _src_sub, _dst_sub, _call, _peerid, data) group_data(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
return return
elif (_packettype == PVT_DATA): elif (_packettype == PVT_DATA):
self._notify_event(self._network, 'private_voice', {'peer_id': _dec_peerid}) self._notify_event(self._network, 'private_voice', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
private_data(self._network, _src_sub, _dst_sub, _call, _peerid, data) private_data(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
return return
return return
@ -751,7 +714,7 @@ class IPSC(DatagramProtocol):
# Packets types that must be originated from a peer # Packets types that must be originated from a peer
if (_packettype in PEER_REQUIRED): if (_packettype in PEER_REQUIRED):
if valid_peer(self._peer_list, _peerid) == False: if valid_peer(self._peer_list, _peerid) == False:
logger.warning('(%s) PeerError: Peer %s not in peer-list: %s', self._network, _dec_peerid, self._peer_list) logger.warning('(%s) PeerError: Peer %s not in peer-list: %s', self._network, int(binascii.b2a_hex(_peerid), 16), self._peer_list)
return return
# Packets we send... # Packets we send...
@ -766,7 +729,7 @@ class IPSC(DatagramProtocol):
self.transport.write(peer_reg_reply_packet, (host, port)) self.transport.write(peer_reg_reply_packet, (host, port))
return return
# Packets we recieve... # Packets we receive...
elif (_packettype == PEER_ALIVE_REPLY): elif (_packettype == PEER_ALIVE_REPLY):
for peer in self._config['PEERS']: for peer in self._config['PEERS']:
if peer['RADIO_ID'] == _peerid: if peer['RADIO_ID'] == _peerid:
@ -782,9 +745,10 @@ class IPSC(DatagramProtocol):
# Packets types that must be originated from a Master # Packets types that must be originated from a Master
# Packets we receive...
if (_packettype in MASTER_REQUIRED): if (_packettype in MASTER_REQUIRED):
if valid_master(self._network, _peerid) == False: if valid_master(self._network, _peerid) == False:
logger.warning('(%s) PeerError: Master %s is invalid: %s', self._network, _dec_peerid, self._peer_list) logger.warning('(%s) PeerError: Master %s is invalid: %s', self._network, int(binascii.b2a_hex(_peerid), 16), self._peer_list)
return return
if (_packettype == MASTER_ALIVE_REPLY): if (_packettype == MASTER_ALIVE_REPLY):
@ -815,9 +779,10 @@ class IPSC(DatagramProtocol):
# 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! # 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: else:
unknown_message(self._network, _packettype, data) unknown_message(self._network, _packettype, _peerid, data)
return return
#************************************************ #************************************************
# Derived Class # Derived Class
# used in the rare event of an # used in the rare event of an

View File

@ -48,4 +48,14 @@ XNL_SLAVE_MSK = 0b00100000
PKT_AUTH_MSK = 0b00010000 PKT_AUTH_MSK = 0b00010000
DATA_CALL_MSK = 0b00001000 DATA_CALL_MSK = 0b00001000
VOICE_CALL_MSK = 0b00000100 VOICE_CALL_MSK = 0b00000100
MSTR_PEER_MSK = 0b00000001 MSTR_PEER_MSK = 0b00000001
# TIMESLOT CALL & STATUS BYTE
# Byte 17 of Group and Private Voice/Data Packets
# ..x.. ....TS Value (0=TS1, 1=TS2)
# .x... ....TS In Progress/End (0=In Progress, 1=End)
# Possible values: 0x00=TS1, 0x20=TS2, 0x40=TS1 End, 0x60=TS2 End
# MASK VALUE:
END_MSK = 0b01000000
TS_CALL_MSK = 0b00100000