Skip to content

Commit

Permalink
TIMESLOT TRANSLATION WORKS!
Browse files Browse the repository at this point in the history
  • Loading branch information
n0mjs710 committed Sep 19, 2014
1 parent 324c166 commit 648569e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 46 deletions.
61 changes: 59 additions & 2 deletions bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@
__status__ = 'beta'


BURST_DATA_TYPE = {
'VOICE_HEAD': '\x01',
'VOICE_TERM': '\x02',
'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
Expand All @@ -70,7 +77,9 @@
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'])
print()
_rule['SRC_TS'] = _rule['SRC_TS'] - 1
_rule['DST_TS'] = _rule['DST_TS'] - 1


# Import List of Bridges
# This is how we identify known bridges. If one of these is present
Expand Down Expand Up @@ -154,6 +163,30 @@ def group_voice(self, _network, _src_sub, _dst_group, _ts, _end, _peerid, _data)
_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
_burst_data_type = _data[30]
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']:
Expand Down Expand Up @@ -184,15 +217,39 @@ def group_voice(self, _network, _src_sub, _dst_group, _ts, _end, _peerid, _data)
# timer = time()

for rule in RULES[_network]['GROUP_VOICE']:
_target = rule['DST_NET']
# 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:
_tmp_data = _data
_target = rule['DST_NET']
# 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
_burst_data_type = _data[30]
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)
Expand Down
12 changes: 6 additions & 6 deletions bridge_rules_SAMPLE.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@
as "active" in the dmrlink.cfg *MUST* have an entry here. It may be an empty entry,
but there must be one so that the data structure can be parsed.
The example below cross-patches TGID 1 on an IPSC network named "IPSC_FOO" with TGID 2
on an IPSC network named "IPSC_BAR". Note, one entry must be made on EACH IPSC network
(IPSC_FOO and IPSC_BAR in this example) for bridging to occur in both directions.
The example below cross-patches TS 1/TGID 1 on an IPSC network named "IPSC_FOO" with
TS 2/TGID 2 on an IPSC network named "IPSC_BAR". Note, one entry must be made on EACH
IPSC network (IPSC_FOO and IPSC_BAR in this example) for bridging to occur in both
directions.
THIS EXAMPLE WILL NOT WORK AS IT IS - YOU MUST SPECIFY NAMES AND GROUP IDS!!!
NOTES:
* Timeslot transcoding does not yet work (SRC_TS) and (DST_TS) are ignored.
* Only GROUP_VOICE is currently used by the bridge.py appication, the other
types are placeholders for when it does more.
'''

RULES = {
'IPSC_FOO': {
'GROUP_VOICE': [
{'SRC_GROUP': 1, 'SRC_TS': 1, 'DST_NET': 'IPSC_BAR', 'DST_GROUP': 2, 'DST_TS': 1},
{'SRC_GROUP': 1, 'SRC_TS': 1, 'DST_NET': 'IPSC_BAR', 'DST_GROUP': 2, 'DST_TS': 2},
# Repeat the above line for as many rules for this IPSC network as you want.
],
'PRIVATE_VOICE': [
Expand All @@ -37,7 +37,7 @@
},
'IPSC_BAR': {
'GROUP_VOICE': [
{'SRC_GROUP': 2, 'SRC_TS': 1, 'DST_NET': 'IPSC_FOO', 'DST_GROUP': 1, 'DST_TS': 1},
{'SRC_GROUP': 2, 'SRC_TS': 2, 'DST_NET': 'IPSC_FOO', 'DST_GROUP': 1, 'DST_TS': 1},
# Repeat the above line for as many rules for this IPSC network as you want.
],
'PRIVATE_VOICE': [
Expand Down
46 changes: 8 additions & 38 deletions ipsc/ipsc_message_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,41 +111,11 @@
}


# Conditions for accepting certain types of messages... the cornerstone of a secure IPSC system :)
'''
REQ_VALID_PEER = [
PEER_REG_REQ,
PEER_REG_REPLY
]
REQ_VALID_MASTER = [
MASTER_REG_REQ,
MASTER_REG_REPLY
]
REQ_MASTER_CONNECTED = [
CALL_MON_STATUS,
CALL_MON_RPT,
CALL_MON_NACK,
XCMP_XNL,
GROUP_VOICE,
PVT_VOICE,
GROUP_DATA,
GROUP_VOICE,
PVT_DATA,
RPT_WAKE_UP,
MASTER_ALIVE_REQ,
MASTER_ALIVE_REPLY,
DE_REG_REQ,
DE_REG_REPLY
]
REQ_PEER_CONNECTED = [
PEER_ALIVE_REQ,
PEER_ALIVE_REPLY
]
REQ_VALID_MASTER_OR_PEER = [
REQ_VALID_PEER, REQ_VALID_MASTER
]
'''
# DMR IPSC Contants (in the RTP Payload)

BURST_DATA_TYPE = {
'VOICE_HEAD': '\x01',
'VOICE_TERM': '\x02',
'SLOT1_VOICE': '\x0A',
'SLOT2_VOICE': '\x8A'
}

0 comments on commit 648569e

Please sign in to comment.