From 9670a8bec42e4f3ffce2cd6c9619a6fc05354eb7 Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Fri, 18 Nov 2016 17:10:48 -0600 Subject: [PATCH] Abandon Stream ID for contention handling Moved back to the system used in DMRlink, and removed dependence on Stream ID. --- hb_router.py | 75 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/hb_router.py b/hb_router.py index f5d1887..beda277 100755 --- a/hb_router.py +++ b/hb_router.py @@ -109,6 +109,8 @@ class routerSYSTEM(HBSYSTEM): # In TX_EMB_LC, 2-5 are burst B-E self.STATUS = { 1: { + 'RX_START': time(), + 'RX_SEQ': '\x00', 'RX_RFS': '\x00', 'TX_RFS': '\x00', 'RX_STREAM_ID': '\x00', @@ -129,6 +131,8 @@ class routerSYSTEM(HBSYSTEM): } }, 2: { + 'RX_START': time(), + 'RX_SEQ': '\x00', 'RX_RFS': '\x00', 'TX_RFS': '\x00', 'RX_STREAM_ID': '\x00', @@ -152,7 +156,6 @@ class routerSYSTEM(HBSYSTEM): def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data): pkt_time = time() - new_stream = False dmrpkt = _data[20:53] _bits = int_id(_data[15]) @@ -165,7 +168,7 @@ class routerSYSTEM(HBSYSTEM): return # This is a new call stream - new_stream = True + self.STATUS['RX_START'] = pkt_time logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s', self._system, int_id(_stream_id), sub_alias(_rf_src), int_id(_rf_src), peer_alias(_radio_id), int_id(_radio_id), tg_alias(_dst_id), int_id(_dst_id), _slot) # If we can, use the LC from the voice header as to keep all options intact @@ -188,10 +191,31 @@ class routerSYSTEM(HBSYSTEM): # BEGIN CONTENTION HANDLING # # 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 TX to the target HBP system, but it has been less than Group Hangtime - # From the same group as the last TX to the target HBP system, but stream ID is different, and it is less than stream timout + # From a different group than last RX from this HBSystem, but it has been less than Group Hangtime + # From a different group than last TX to this HBSystem, but it has been less than Group Hangtime + # From the same group as the last RX from this HBSystem, but from a different subscriber, and it has been less than stream timeout + # From the same group as the last TX to this HBSystem, but from a different subscriber, and it has been less than stream timeout # The "continue" at the end of each means the next iteration of the for loop that tests for matching rules # + if ((rule['DST_GROUP'] != _target_status[_slot]['RX_TGID']) and ((pkt_time - _target_status[_slot]['RX_TIME']) < RULES[_target]['GROUP_HANGTIME'])): + if True: #if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: + logger.info('(%s) Call not routed to TGID%s, target active or in group hangtime: HBSystem %s, %s, TGID%s', self._system, int_id(_target_status[_slot]['TX_TGID']), _target, _slot, int_id(rule['DST_GROUP'])) + continue + if ((rule['DST_GROUP'] != _target_status[_slot]['TX_TGID']) and ((pkt_time - _target_status[_slot]['TX_TIME']) < RULES[_target]['GROUP_HANGTIME'])): + if True: #if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: + logger.info('(%s) Call not routed to TGID%s, target in group hangtime: HBSystem %s, %s, TGID%s', self._system, int_id(_target_status[_slot]['TX_TGID']), _target, _slot, int_id(rule['DST_GROUP'])) + continue + if (rule['DST_GROUP'] == _target_status[_slot]['RX_TGID']) and ((pkt_time - self.STATUS[_slot]['RX_TIME']) < const.STREAM_TO): + if True: #if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: + print(repr(rule['DST_GROUP']), repr(self.STATUS[_slot]['RX_TGID']), pkt_time, self.STATUS[_slot]['RX_TIME'], const.STREAM_TO) + logger.info('(%s) Call not routed, matching call already active on target: HBSystem %s, %s, TGID%s', self._system, _target, _slot, int_id(rule['DST_GROUP'])) + continue + if (rule['DST_GROUP'] == _target_status[_slot]['TX_TGID']) and (_rf_src != _target_status[_slot]['TX_RFS']) and ((pkt_time - self.STATUS[_slot]['TX_TIME']) < const.STREAM_TO): + if True: #if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: + logger.info('(%s) Call not routed, call route in progress from %s, target: HBSystem %s, %s, TGID%s', self._system, _target_status[_slot]['TX_RFS'], _target, _slot, int_id(rule['DST_GROUP'])) + continue + + ''' if ((rule['DST_GROUP'] != _target_status[_slot]['TX_TGID']) and ((pkt_time - self.STATUS[_slot]['RX_TIME']) < RULES[self._system]['GROUP_HANGTIME'])): if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: logger.info('(%s) Call not routed, target active or in group hangtime: HBP system %s, TS%s, TGID%s', self._system, _target, _slot, int_id(rule['DST_GROUP'])) @@ -200,7 +224,7 @@ class routerSYSTEM(HBSYSTEM): if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: logger.info('(%s) Call not routed, call in progress: %s, target: HBP system %s, TS%s, TGID%s', self._system, int_id(_src_sub), _target, _slot, int_id(rule['DST_GROUP'])) continue - + ''' # Set values for the contention handler to test next time there is a frame to forward _target_status[_slot]['TX_TIME'] = pkt_time @@ -210,12 +234,12 @@ class routerSYSTEM(HBSYSTEM): _target_status[_slot]['TX_STREAM_ID'] = _stream_id _target_status[_slot]['TX_RFS'] = _rf_src # Generate LCs (full and EMB) for the TX stream - if True: #_dst_id != rule['DST_GROUP']: - dst_lc = self.STATUS[_slot]['RX_LC'][0:3] + rule['DST_GROUP'] + _rf_src - _target_status[_slot]['TX_H_LC'] = bptc.encode_header_lc(dst_lc) - _target_status[_slot]['TX_T_LC'] = bptc.encode_terminator_lc(dst_lc) - _target_status[_slot]['TX_EMB_LC'] = bptc.encode_emblc(dst_lc) - logger.debug('(%s) Packet DST TGID (%s) does not match SRC TGID(%s) - Generating FULL and EMB LCs', self._system, int_id(rule['DST_GROUP']), int_id(_dst_id)) + # if _dst_id != rule['DST_GROUP']: + dst_lc = self.STATUS[_slot]['RX_LC'][0:3] + rule['DST_GROUP'] + _rf_src + _target_status[_slot]['TX_H_LC'] = bptc.encode_header_lc(dst_lc) + _target_status[_slot]['TX_T_LC'] = bptc.encode_terminator_lc(dst_lc) + _target_status[_slot]['TX_EMB_LC'] = bptc.encode_emblc(dst_lc) + logger.debug('(%s) Packet DST TGID (%s) does not match SRC TGID(%s) - Generating FULL and EMB LCs', self._system, int_id(rule['DST_GROUP']), int_id(_dst_id)) # Handle any necessary re-writes for the destination if rule['SRC_TS'] != rule['DST_TS']: @@ -228,19 +252,19 @@ class routerSYSTEM(HBSYSTEM): # MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET # MUST RE-WRITE DESTINATION TGID IF DIFFERENT - if True: #_dst_id != rule['DST_GROUP']: - dmrbits = bitarray(endian='big') - dmrbits.frombytes(dmrpkt) - # Create a voice header packet (FULL LC) - if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: - dmrbits = _target_status[_slot]['TX_H_LC'][0:98] + dmrbits[98:166] + _target_status[_slot]['TX_H_LC'][98:197] - # Create a voice terminator packet (FULL LC) - elif _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VTERM: - dmrbits = _target_status[_slot]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_slot]['TX_T_LC'][98:197] - # Create a Burst B-E packet (Embedded LC) - elif _dtype_vseq in [1,2,3,4]: - dmrbits = dmrbits[0:116] + _target_status[_slot]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264] - dmrpkt = dmrbits.tobytes() + # if _dst_id != rule['DST_GROUP']: + dmrbits = bitarray(endian='big') + dmrbits.frombytes(dmrpkt) + # Create a voice header packet (FULL LC) + if _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VHEAD: + dmrbits = _target_status[_slot]['TX_H_LC'][0:98] + dmrbits[98:166] + _target_status[_slot]['TX_H_LC'][98:197] + # Create a voice terminator packet (FULL LC) + elif _frame_type == const.HBPF_DATA_SYNC and _dtype_vseq == const.HBPF_SLT_VTERM: + dmrbits = _target_status[_slot]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_slot]['TX_T_LC'][98:197] + # Create a Burst B-E packet (Embedded LC) + elif _dtype_vseq in [1,2,3,4]: + dmrbits = dmrbits[0:116] + _target_status[_slot]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264] + dmrpkt = dmrbits.tobytes() _tmp_data = _tmp_data + dmrpkt + _data[53:55] # Transmit the packet to the destination system @@ -251,7 +275,8 @@ class routerSYSTEM(HBSYSTEM): # Final actions - Is this a voice terminator? if (_frame_type == const.HBPF_DATA_SYNC) and (_dtype_vseq == const.HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != const.HBPF_SLT_VTERM): - logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s', self._system, int_id(_stream_id), sub_alias(_rf_src), int_id(_rf_src), peer_alias(_radio_id), int_id(_radio_id), tg_alias(_dst_id), int_id(_dst_id), _slot) + call_duration = pkt_time - self.STATUS['RX_START'] + logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) REPEATER: %s (%s) TGID %s (%s), TS %s, Duration: %s', self._system, int_id(_stream_id), sub_alias(_rf_src), int_id(_rf_src), peer_alias(_radio_id), int_id(_radio_id), tg_alias(_dst_id), int_id(_dst_id), _slot, call_duration) # Mark status variables for use later self.STATUS[_slot]['RX_RFS'] = _rf_src