Name Change - Function Re-Org
Preparing to use DMRlink as a python module. The name needed to be changed to not clash with the resource sub-directory, and functions were moved into the main class that are intended to be changed in a derived class. DMRlink is now a functional module. I will be shifting ALL development of "application" level features to other files with derived classes, and dmrlink.py will ONLY include protocol update/fixes/etc.
This commit is contained in:
parent
3cb242d368
commit
9f53e7035b
@ -47,7 +47,6 @@ try:
|
||||
except ImportError:
|
||||
sys.exit('IPSC mask values file not found or invalid')
|
||||
|
||||
|
||||
ids = {}
|
||||
try:
|
||||
with open('./radioids.csv', 'r') as radioids_csv:
|
||||
@ -91,13 +90,16 @@ except ImportError:
|
||||
.... ...x = Set if master
|
||||
'''
|
||||
|
||||
ACTIVE_CALLS = []
|
||||
networks = {}
|
||||
NETWORK = {}
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read('./dmrlink.cfg')
|
||||
|
||||
for section in config.sections():
|
||||
if section == 'GLOBAL':
|
||||
pass
|
||||
else:
|
||||
NETWORK.update({section: {'LOCAL': {}, 'MASTER': {}, 'PEERS': []}})
|
||||
NETWORK[section]['LOCAL'].update({
|
||||
'MODE': '',
|
||||
@ -151,93 +153,6 @@ for section in config.sections():
|
||||
else:
|
||||
NETWORK[section]['LOCAL']['MODE'] = '\x6A'
|
||||
|
||||
#************************************************
|
||||
# CALLBACK FUNCTIONS FOR USER PACKET TYPES
|
||||
#************************************************
|
||||
|
||||
def call_ctl_1(_network, _data):
|
||||
print('({}) Call Control Type 1 Packet Received From: {}' .format(_network, _src_sub))
|
||||
|
||||
def call_ctl_2(_network, _data):
|
||||
print('({}) Call Control Type 2 Packet Received' .format(_network))
|
||||
|
||||
def call_ctl_3(_network, _data):
|
||||
print('({}) Call Control Type 3 Packet Received' .format(_network))
|
||||
|
||||
def xcmp_xnl(_network, _data):
|
||||
print('({}) XCMP/XNL Packet Received From: {}' .format(_network, _src_sub))
|
||||
|
||||
def group_voice(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
# _log = logger.debug
|
||||
if ((_network, _ts) not in ACTIVE_CALLS) or _end:
|
||||
_time = time.strftime('%m/%d/%y %H:%M:%S')
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
if not _end: ACTIVE_CALLS.append((_network, _ts))
|
||||
if _end: ACTIVE_CALLS.remove((_network, _ts))
|
||||
|
||||
if _ts: _ts = 2
|
||||
else: _ts = 1
|
||||
if _end: _end = 'END'
|
||||
else: _end = 'START'
|
||||
|
||||
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))
|
||||
|
||||
'''
|
||||
for source in NETWORK[_network]['RULES']['GROUP_VOICE']:
|
||||
# Matching for rules is against the Destination Group in the SOURCE packet (SRC_GROUP)
|
||||
if source['SRC_GROUP'] == _src_group:
|
||||
_target = source['DST_NET']
|
||||
_target_sock = NETWORK[_target]['MASTER']['IP'], NETWORK[_target]['MASTER']['PORT']
|
||||
# Re-Write the IPSC SRC to match the target network's ID
|
||||
_data = _data.replace(_peerid, NETWORK[_target]['LOCAL']['RADIO_ID'])
|
||||
# Re-Write the destinaion Group ID
|
||||
_data = _data.replace(_src_group, source['DST_GROUP'])
|
||||
# Calculate and append the authentication hash for the target network... if necessary
|
||||
if NETWORK[_target]['LOCAL']['AUTH_KEY'] == True:
|
||||
_data = hashed_packet(NETWORK[_target]['LOCAL']['AUTH_KEY'], _data)
|
||||
# Send the packet to all peers in the target IPSC
|
||||
send_to_ipsc(_target, _data)
|
||||
'''
|
||||
|
||||
def private_voice(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
# _log = logger.debug
|
||||
if ((_network, _ts) not in ACTIVE_CALLS) or _end:
|
||||
_time = time.strftime('%m/%d/%y %H:%M:%S')
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
if not _end: ACTIVE_CALLS.append((_network, _ts))
|
||||
if _end: ACTIVE_CALLS.remove((_network, _ts))
|
||||
|
||||
if _ts: _ts = 2
|
||||
else: _ts = 1
|
||||
if _end: _end = 'END'
|
||||
else: _end = 'START'
|
||||
|
||||
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))
|
||||
|
||||
def group_data(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
print('({}) Group Data Packet Received From: {}' .format(_network, _src_sub))
|
||||
|
||||
def private_data(_network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
print('({}) Private Data Packet Received From: {} To: {}' .format(_network, _src_sub, _dst_sub))
|
||||
|
||||
def unknown_message(_network, _packettype, _peerid, _data):
|
||||
_time = time.strftime('%m/%d/%y %H:%M:%S')
|
||||
_packettype = binascii.b2a_hex(_packettype)
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
print('{} ({}) Unknown message type encountered\n\tPacket Type: {}\n\tFrom: {}' .format(_time, _network, _packettype, _peerid))
|
||||
print('\t', binascii.b2a_hex(_data))
|
||||
|
||||
|
||||
|
||||
#************************************************
|
||||
# UTILITY FUNCTIONS FOR INTERNAL USE
|
||||
@ -479,8 +394,13 @@ class IPSC(DatagramProtocol):
|
||||
# We have to know when we have a new peer list, so a variable to indicate we do (or don't)
|
||||
#
|
||||
self._peer_list = []
|
||||
#
|
||||
# A place to keep track of calls that are active on this IPSC
|
||||
self.ACTIVE_CALLS = []
|
||||
|
||||
args = ()
|
||||
|
||||
|
||||
# Packet 'constructors' - builds the necessary control packets for this IPSC instance.
|
||||
# This isn't really necessary for anything other than readability (reduction of code golf)
|
||||
#
|
||||
@ -514,6 +434,92 @@ class IPSC(DatagramProtocol):
|
||||
self._reporting = task.LoopingCall(self.reporting_loop)
|
||||
self._reporting_loop = self._reporting.start(10)
|
||||
|
||||
#************************************************
|
||||
# CALLBACK FUNCTIONS FOR USER PACKET TYPES
|
||||
#************************************************
|
||||
|
||||
def call_ctl_1(self, _network, _data):
|
||||
print('({}) Call Control Type 1 Packet Received From: {}' .format(_network, _src_sub))
|
||||
|
||||
def call_ctl_2(self, _network, _data):
|
||||
print('({}) Call Control Type 2 Packet Received' .format(_network))
|
||||
|
||||
def call_ctl_3(self, _network, _data):
|
||||
print('({}) Call Control Type 3 Packet Received' .format(_network))
|
||||
|
||||
def xcmp_xnl(self, _network, _data):
|
||||
print('({}) XCMP/XNL Packet Received From: {}' .format(_network, _src_sub))
|
||||
|
||||
def group_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
# _log = logger.debug
|
||||
if (_ts not in self.ACTIVE_CALLS) or _end:
|
||||
_time = time.strftime('%m/%d/%y %H:%M:%S')
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
if not _end: self.ACTIVE_CALLS.append(_ts)
|
||||
if _end: self.ACTIVE_CALLS.remove(_ts)
|
||||
|
||||
if _ts: _ts = 2
|
||||
else: _ts = 1
|
||||
if _end: _end = 'END'
|
||||
else: _end = 'START'
|
||||
|
||||
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))
|
||||
|
||||
'''
|
||||
for source in NETWORK[_network]['RULES']['GROUP_VOICE']:
|
||||
# Matching for rules is against the Destination Group in the SOURCE packet (SRC_GROUP)
|
||||
if source['SRC_GROUP'] == _src_group:
|
||||
_target = source['DST_NET']
|
||||
_target_sock = NETWORK[_target]['MASTER']['IP'], NETWORK[_target]['MASTER']['PORT']
|
||||
# Re-Write the IPSC SRC to match the target network's ID
|
||||
_data = _data.replace(_peerid, NETWORK[_target]['LOCAL']['RADIO_ID'])
|
||||
# Re-Write the destinaion Group ID
|
||||
_data = _data.replace(_src_group, source['DST_GROUP'])
|
||||
# Calculate and append the authentication hash for the target network... if necessary
|
||||
if NETWORK[_target]['LOCAL']['AUTH_KEY'] == True:
|
||||
_data = hashed_packet(NETWORK[_target]['LOCAL']['AUTH_KEY'], _data)
|
||||
# Send the packet to all peers in the target IPSC
|
||||
send_to_ipsc(_target, _data)
|
||||
'''
|
||||
|
||||
def private_voice(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
# _log = logger.debug
|
||||
if ((_network, _ts) not in self.ACTIVE_CALLS) or _end:
|
||||
_time = time.strftime('%m/%d/%y %H:%M:%S')
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
if not _end: self.ACTIVE_CALLS.append((_network, _ts))
|
||||
if _end: self.ACTIVE_CALLS.remove((_network, _ts))
|
||||
|
||||
if _ts: _ts = 2
|
||||
else: _ts = 1
|
||||
if _end: _end = 'END'
|
||||
else: _end = 'START'
|
||||
|
||||
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))
|
||||
|
||||
def group_data(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
print('({}) Group Data Packet Received From: {}' .format(_network, _src_sub))
|
||||
|
||||
def private_data(self, _network, _src_sub, _dst_sub, _ts, _end, _peerid, _data):
|
||||
_dst_sub = get_info(int_id(_dst_sub))
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
_src_sub = get_info(int_id(_src_sub))
|
||||
print('({}) Private Data Packet Received From: {} To: {}' .format(_network, _src_sub, _dst_sub))
|
||||
|
||||
def unknown_message(self, _network, _packettype, _peerid, _data):
|
||||
_time = time.strftime('%m/%d/%y %H:%M:%S')
|
||||
_packettype = binascii.b2a_hex(_packettype)
|
||||
_peerid = get_info(int_id(_peerid))
|
||||
print('{} ({}) Unknown message type encountered\n\tPacket Type: {}\n\tFrom: {}' .format(_time, _network, _packettype, _peerid))
|
||||
print('\t', binascii.b2a_hex(_data))
|
||||
|
||||
|
||||
# Take a packet to be SENT, calcualte auth hash and return the whole thing
|
||||
#
|
||||
@ -675,40 +681,40 @@ class IPSC(DatagramProtocol):
|
||||
# User Voice and Data Call Types:
|
||||
if (_packettype == GROUP_VOICE):
|
||||
self._notify_event(self._network, 'group_voice', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
|
||||
group_voice(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
self.group_voice(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
return
|
||||
|
||||
elif (_packettype == PVT_VOICE):
|
||||
self._notify_event(self._network, 'private_voice', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
|
||||
private_voice(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
self.private_voice(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
return
|
||||
|
||||
elif (_packettype == GROUP_DATA):
|
||||
self._notify_event(self._network, 'group_data', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
|
||||
group_data(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
self.group_data(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
return
|
||||
|
||||
elif (_packettype == PVT_DATA):
|
||||
self._notify_event(self._network, 'private_voice', {'peer_id': int(binascii.b2a_hex(_peerid), 16)})
|
||||
private_data(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
self.private_data(self._network, _src_sub, _dst_sub, _ts, _end, _peerid, data)
|
||||
return
|
||||
return
|
||||
|
||||
# Other peer-required types that we don't do much or anything with yet
|
||||
elif (_packettype == XCMP_XNL):
|
||||
xcmp_xnl(self._network, data)
|
||||
self.xcmp_xnl(self._network, data)
|
||||
return
|
||||
|
||||
elif (_packettype == CALL_CTL_1):
|
||||
call_ctl_1(self._network, data)
|
||||
self.call_ctl_1(self._network, data)
|
||||
return
|
||||
|
||||
elif (_packettype == CALL_CTL_2):
|
||||
call_ctl_2(self._network, data)
|
||||
self.call_ctl_2(self._network, data)
|
||||
return
|
||||
|
||||
elif (_packettype == CALL_CTL_3):
|
||||
call_ctl_3(self._network, data)
|
||||
self.call_ctl_3(self._network, data)
|
||||
return
|
||||
|
||||
# Connection maintenance packets that fall into this category
|
||||
@ -795,7 +801,7 @@ 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!
|
||||
else:
|
||||
unknown_message(self._network, _packettype, _peerid, data)
|
||||
self.unknown_message(self._network, _packettype, _peerid, data)
|
||||
return
|
||||
|
||||
|
||||
@ -823,7 +829,7 @@ class UnauthIPSC(IPSC):
|
||||
#************************************************
|
||||
|
||||
if __name__ == '__main__':
|
||||
networks = {}
|
||||
#networks = {}
|
||||
for ipsc_network in NETWORK:
|
||||
if (NETWORK[ipsc_network]['LOCAL']['ENABLED']):
|
||||
if NETWORK[ipsc_network]['LOCAL']['AUTH_ENABLED'] == True:
|
Loading…
Reference in New Issue
Block a user