From b44be39a164fc58102870c61c3c01822a6c565f4 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 01:46:28 +0100 Subject: [PATCH 01/39] Move where dup seq. is recorded --- bridge_master.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index e6f588a..c8cd668 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1259,6 +1259,9 @@ class routerOBP(OPENBRIDGE): elif _seq == True and _seq > (self._lastSeq+1): logger.debug("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) + #Save this sequence number + self._lastSeq = _seq + if _call_type == 'group': # Is this a new call stream? @@ -1330,8 +1333,6 @@ class routerOBP(OPENBRIDGE): self.STATUS[_stream_id]['LAST'] = pkt_time - #Save this sequence number - self._lastSeq = _seq #Create STAT bridge for unknown TG if CONFIG['GLOBAL']['GEN_STAT_BRIDGES']: From 9084eacc23cb2457b62b530a9d096d62148a8893 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 01:47:32 +0100 Subject: [PATCH 02/39] Sequence number logging at warning level --- bridge_master.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index c8cd668..b3381a6 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1249,15 +1249,15 @@ class routerOBP(OPENBRIDGE): #Handle inbound duplicates if _seq == True and _seq == self._lastSeq: - logger.debug("%s) Duplicate sequence number %s, disgarding",self._system,_seq) + logger.warning("%s) Duplicate sequence number %s, disgarding",self._system,_seq) return #Inbound out-of-order packets elif _seq == True and (_seq != 1) and (_seq < self._lastSeq): - logger.debug("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) + logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) return #Inbound missed packets elif _seq == True and _seq > (self._lastSeq+1): - logger.debug("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) + logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) #Save this sequence number self._lastSeq = _seq From 84a92d89632cf18b5e6144b89eec61404c6695ea Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 01:57:08 +0100 Subject: [PATCH 03/39] Compare whole packet for duplicates --- bridge_master.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index b3381a6..5a66de7 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1081,6 +1081,8 @@ class routerOBP(OPENBRIDGE): #Store last sequence number self._lastSeq = False + #store last packet + self._lastData = False def to_target(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,_noOBP,sysIgnore): _sysIgnore = sysIgnore @@ -1247,20 +1249,26 @@ class routerOBP(OPENBRIDGE): dmrpkt = _data[20:53] _bits = _data[15] + #Duplicate complete packet + if self._lastData and _lastData == _data: + logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) + return + #Handle inbound duplicates - if _seq == True and _seq == self._lastSeq: - logger.warning("%s) Duplicate sequence number %s, disgarding",self._system,_seq) + if _seq and _seq == self._lastSeq: + logger.warning("(%s) Duplicate sequence number %s, disgarding",self._system,_seq) return #Inbound out-of-order packets - elif _seq == True and (_seq != 1) and (_seq < self._lastSeq): + if _seq and (_seq != 1) and (_seq < self._lastSeq): logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) return #Inbound missed packets - elif _seq == True and _seq > (self._lastSeq+1): + if _seq and _seq > (self._lastSeq+1): logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) #Save this sequence number self._lastSeq = _seq + self._lastData = _data if _call_type == 'group': From 94418256ec5ac5e61f56483d4d74c2c5f7923014 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 02:09:45 +0100 Subject: [PATCH 04/39] Make sure we always record last time, even if packet rejected by LoopControl --- bridge_master.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 5a66de7..3fb4479 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1272,6 +1272,11 @@ class routerOBP(OPENBRIDGE): if _call_type == 'group': + + + #Put this here as I think we risk timing out a stream too soon if it is rejected + self.STATUS[_stream_id]['LAST'] = pkt_time + # Is this a new call stream? if (_stream_id not in self.STATUS): @@ -1339,7 +1344,6 @@ class routerOBP(OPENBRIDGE): return - self.STATUS[_stream_id]['LAST'] = pkt_time #Create STAT bridge for unknown TG From 0503e726075f8fd284b87d54d8d6482f370fc481 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 02:18:50 +0100 Subject: [PATCH 05/39] lastdata --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 3fb4479..df9231f 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1250,7 +1250,7 @@ class routerOBP(OPENBRIDGE): _bits = _data[15] #Duplicate complete packet - if self._lastData and _lastData == _data: + if self._lastData and self._lastData == _data: logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) return From 8749a457c34a4075d173d281d2f02b1a81332d0d Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 10:49:01 +0100 Subject: [PATCH 06/39] Revert "lastdata" This reverts commit 0503e726075f8fd284b87d54d8d6482f370fc481. --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index df9231f..3fb4479 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1250,7 +1250,7 @@ class routerOBP(OPENBRIDGE): _bits = _data[15] #Duplicate complete packet - if self._lastData and self._lastData == _data: + if self._lastData and _lastData == _data: logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) return From 250b0789b6728994f4c3b61f26a434ca93e876ef Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 10:49:02 +0100 Subject: [PATCH 07/39] Revert "Make sure we always record last time, even if packet rejected by LoopControl" This reverts commit 94418256ec5ac5e61f56483d4d74c2c5f7923014. --- bridge_master.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 3fb4479..5a66de7 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1272,11 +1272,6 @@ class routerOBP(OPENBRIDGE): if _call_type == 'group': - - - #Put this here as I think we risk timing out a stream too soon if it is rejected - self.STATUS[_stream_id]['LAST'] = pkt_time - # Is this a new call stream? if (_stream_id not in self.STATUS): @@ -1344,6 +1339,7 @@ class routerOBP(OPENBRIDGE): return + self.STATUS[_stream_id]['LAST'] = pkt_time #Create STAT bridge for unknown TG From 51e7d50d1e401a932a834ae7f25292955c282545 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 10:53:53 +0100 Subject: [PATCH 08/39] Only compare whole packet is seq > 1 --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 5a66de7..23818a3 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1250,7 +1250,7 @@ class routerOBP(OPENBRIDGE): _bits = _data[15] #Duplicate complete packet - if self._lastData and _lastData == _data: + if self._lastData and _lastData == _data and _seq > 1: logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) return From 4de29e3c7783458a0509b9ae54f5f331b600d0ce Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 10:56:28 +0100 Subject: [PATCH 09/39] self.lastData --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 23818a3..78ac2ed 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1250,7 +1250,7 @@ class routerOBP(OPENBRIDGE): _bits = _data[15] #Duplicate complete packet - if self._lastData and _lastData == _data and _seq > 1: + if self._lastData and self._lastData == _data and _seq > 1: logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) return From fa3dda2c2fb8262616b880374fe9303d2eb80e60 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 10:59:46 +0100 Subject: [PATCH 10/39] Handle false lastSeq --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 78ac2ed..0bcec9b 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1259,7 +1259,7 @@ class routerOBP(OPENBRIDGE): logger.warning("(%s) Duplicate sequence number %s, disgarding",self._system,_seq) return #Inbound out-of-order packets - if _seq and (_seq != 1) and (_seq < self._lastSeq): + if _seq and self._lastSeq and (_seq != 1) and (_seq < self._lastSeq): logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) return #Inbound missed packets From 10bff82d6b1a3bc52854611ea6d887224b9b1764 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 11:02:44 +0100 Subject: [PATCH 11/39] Seq --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 0bcec9b..6e4919e 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1263,7 +1263,7 @@ class routerOBP(OPENBRIDGE): logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) return #Inbound missed packets - if _seq and _seq > (self._lastSeq+1): + if _seq and and self._lastSeq _seq > (self._lastSeq+1): logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) #Save this sequence number From cebdffaf9fa9338805893855c92eba7a04b651af Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 11:03:54 +0100 Subject: [PATCH 12/39] sq --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 6e4919e..f2e4397 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1263,7 +1263,7 @@ class routerOBP(OPENBRIDGE): logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) return #Inbound missed packets - if _seq and and self._lastSeq _seq > (self._lastSeq+1): + if _seq and and self._lastSeq and _seq > (self._lastSeq+1): logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) #Save this sequence number From 5586c438b223c451fd98977e39e19707d63a1b82 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 11:04:33 +0100 Subject: [PATCH 13/39] a --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index f2e4397..79c9e65 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1263,7 +1263,7 @@ class routerOBP(OPENBRIDGE): logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) return #Inbound missed packets - if _seq and and self._lastSeq and _seq > (self._lastSeq+1): + if _seq and self._lastSeq and _seq > (self._lastSeq+1): logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) #Save this sequence number From 5bcc3757923a6cdef184f3d82be4af99c4afbef2 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 18:15:41 +0100 Subject: [PATCH 14/39] More work to fix duplicate detection --- bridge_master.py | 69 +++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 79c9e65..030ac2e 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1078,12 +1078,7 @@ class routerOBP(OPENBRIDGE): def __init__(self, _name, _config, _report): OPENBRIDGE.__init__(self, _name, _config, _report) self.STATUS = {} - - #Store last sequence number - self._lastSeq = False - #store last packet - self._lastData = False - + def to_target(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,_noOBP,sysIgnore): _sysIgnore = sysIgnore for _target in BRIDGES[_bridge]: @@ -1248,29 +1243,7 @@ class routerOBP(OPENBRIDGE): pkt_time = time() dmrpkt = _data[20:53] _bits = _data[15] - - #Duplicate complete packet - if self._lastData and self._lastData == _data and _seq > 1: - logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) - return - - #Handle inbound duplicates - if _seq and _seq == self._lastSeq: - logger.warning("(%s) Duplicate sequence number %s, disgarding",self._system,_seq) - return - #Inbound out-of-order packets - if _seq and self._lastSeq and (_seq != 1) and (_seq < self._lastSeq): - logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) - return - #Inbound missed packets - if _seq and self._lastSeq and _seq > (self._lastSeq+1): - logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) - - #Save this sequence number - self._lastSeq = _seq - self._lastData = _data - - + if _call_type == 'group': # Is this a new call stream? if (_stream_id not in self.STATUS): @@ -1281,8 +1254,12 @@ class routerOBP(OPENBRIDGE): 'CONTENTION':False, 'RFS': _rf_src, 'TGID': _dst_id, - '1ST': True + '1ST': True, + 'lastSeq': False, + 'lastData': False + } + print(self.STATUS[_stream_id]) # If we can, use the LC from the voice header as to keep all options intact if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD: @@ -1302,15 +1279,14 @@ class routerOBP(OPENBRIDGE): else: - - + #Finished stream handling# if '_fin' in self.STATUS[_stream_id]: if '_finlog' not in self.STATUS[_stream_id]: logger.warning("(%s) OBP *LoopControl* STREAM ID: %s ALREADY FINISHED FROM THIS SOURCE, IGNORING",self._system, int_id(_stream_id)) self.STATUS[_stream_id]['_finlog'] = True return - + #LoopControl# for system in systems: if system == self._system: continue @@ -1334,9 +1310,30 @@ class routerOBP(OPENBRIDGE): systems[self._system].send_bcsq(_dst_id,_stream_id) #logger.warning("(%s) OBP *BridgeControl* Sent BCSQ , STREAM ID: %s, TG %s",self._system, int_id(_stream_id), int_id(_dst_id)) self.STATUS[_stream_id]['_bcsq'] = True - - return + + #Duplicate handling# + #Duplicate complete packet + if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: + logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) + return + #Handle inbound duplicates + if _seq and _seq == self.STATUS[_stream_id]['lastSeq']: + logger.warning("(%s) Duplicate sequence number %s, disgarding",self._system,_seq) + return + #Inbound out-of-order packets + if _seq and self.STATUS[_stream_id]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_stream_id]['lastSeq']): + logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self.STATUS[_stream_id]['lastSeq'],_seq) + return + #Inbound missed packets + if _seq and self.STATUS[_stream_id]['lastSeq'] and _seq > (self.STATUS[_stream_id]['lastSeq']+1): + logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self.STATUS[_stream_id]['lastSeq'],_seq) + + #Save this sequence number + self.STATUS[_stream_id]['lastSeq'] = _seq + #Save this packet + self.STATUS[_stream_id]['lastData'] = _data + self.STATUS[_stream_id]['LAST'] = pkt_time @@ -1372,7 +1369,7 @@ class routerOBP(OPENBRIDGE): #selflogger.error('(%s) *CALL END* STREAM ID: %s NOT IN LIST -- THIS IS A REAL PROBLEM', self._system, int_id(_stream_id)) #Reset sequence number - self._lastSeq = False + self.STATUS[_stream_id]['lastSeq'] = False class routerHBP(HBSYSTEM): From 4331bb4e5148baec652a8307de3a7ae2864e1c8a Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 18:29:22 +0100 Subject: [PATCH 15/39] Enhance logging for dup detection --- bridge_master.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 030ac2e..7822410 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1315,19 +1315,19 @@ class routerOBP(OPENBRIDGE): #Duplicate handling# #Duplicate complete packet if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: - logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding",self._system) + logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) return #Handle inbound duplicates if _seq and _seq == self.STATUS[_stream_id]['lastSeq']: - logger.warning("(%s) Duplicate sequence number %s, disgarding",self._system,_seq) + logger.warning("(%s) Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound out-of-order packets if _seq and self.STATUS[_stream_id]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_stream_id]['lastSeq']): - logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self.STATUS[_stream_id]['lastSeq'],_seq) + logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound missed packets if _seq and self.STATUS[_stream_id]['lastSeq'] and _seq > (self.STATUS[_stream_id]['lastSeq']+1): - logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self.STATUS[_stream_id]['lastSeq'],_seq) + logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) #Save this sequence number self.STATUS[_stream_id]['lastSeq'] = _seq From e985951d2ce4d2f0328a5255eb741d7ef18003e4 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 18:31:13 +0100 Subject: [PATCH 16/39] Further enhance dup logging. --- bridge_master.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 7822410..1fdadbe 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1315,19 +1315,19 @@ class routerOBP(OPENBRIDGE): #Duplicate handling# #Duplicate complete packet if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: - logger.warning("(%s) last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *DupControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) return #Handle inbound duplicates if _seq and _seq == self.STATUS[_stream_id]['lastSeq']: - logger.warning("(%s) Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *DupControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound out-of-order packets if _seq and self.STATUS[_stream_id]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_stream_id]['lastSeq']): - logger.warning("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("%s) *DupControl* Out of order packet - last sequence number %s, this sequence number %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound missed packets if _seq and self.STATUS[_stream_id]['lastSeq'] and _seq > (self.STATUS[_stream_id]['lastSeq']+1): - logger.warning("(%s) Missed packet - last sequence number %s, this sequence number %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *DupControl* Missed packet - last sequence number %s, this sequence number %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) #Save this sequence number self.STATUS[_stream_id]['lastSeq'] = _seq From 4c998ccccfc47d32b788f8ba4f39a77067b2ac6f Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 19:07:40 +0100 Subject: [PATCH 17/39] re-enable PEER --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 1fdadbe..71b35c5 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -2086,7 +2086,7 @@ if __name__ == '__main__': for system in CONFIG['SYSTEMS']: if CONFIG['SYSTEMS'][system]['ENABLED']: - if CONFIG['SYSTEMS'][system]['MODE'] == 'XLXPEER' or CONFIG['SYSTEMS'][system]['MODE'] == 'PEER': + if CONFIG['SYSTEMS'][system]['MODE'] == 'XLXPEER': logger.warning('(GLOBAL) system %s not started - XLXPEER and PEER connections currently unsupported ', system) continue if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE': From 090500d32709b20dddb087e6f660e7d104aca29a Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 20:48:14 +0100 Subject: [PATCH 18/39] Duplicate detection for HBP --- bridge_master.py | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 71b35c5..d76a1f7 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1403,7 +1403,9 @@ class routerHBP(HBSYSTEM): 2: b'\x00', 3: b'\x00', 4: b'\x00', - } + }, + 'lastSeq': False, + 'lastData': False }, 2: { 'RX_START': time(), @@ -1429,7 +1431,9 @@ class routerHBP(HBSYSTEM): 2: b'\x00', 3: b'\x00', 4: b'\x00', - } + }, + 'lastSeq': False, + 'lastData': False } } @@ -1765,7 +1769,28 @@ class routerHBP(HBSYSTEM): if int_id(_dst_id) >= 5 and int_id(_dst_id) != 9 and (str(int_id(_dst_id)) not in BRIDGES): logger.info('(%s) Bridge for TG %s does not exist. Creating as User Activated. Timeout %s',self._system, int_id(_dst_id),CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER']) make_single_bridge(_dst_id,self._system,_slot,CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER']) - + + #Duplicate handling# + #Duplicate complete packet + if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: + logger.warning("(%s) *DupControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) + return + #Handle inbound duplicates + if _seq and _seq == self.STATUS[_slot]['lastSeq']: + logger.warning("(%s) *DupControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) + return + #Inbound out-of-order packets + if _seq and self.STATUS[_slot]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_slot]['lastSeq']): + logger.warning("%s) *DupControl* Out of order packet - last sequence number %s, this sequence number %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + return + #Inbound missed packets + if _seq and self.STATUS[_slot]['lastSeq'] and _seq > (self.STATUS[_slot]['lastSeq']+1): + logger.warning("(%s) *DupControl* Missed packet - last sequence number %s, this sequence number %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + + #Save this sequence number + self.STATUS[_slot]['lastSeq'] = _seq + #Save this packet + self.STATUS[_slot]['lastData'] = _data _sysIgnore = [] for _bridge in BRIDGES: @@ -1790,6 +1815,10 @@ class routerHBP(HBSYSTEM): self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration) if CONFIG['REPORTS']['REPORT']: self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration).encode(encoding='utf-8', errors='ignore')) + + #Reset back to False + self.STATUS[_slot]['lastSeq'] = False + self.STATUS[_slot]['lastData'] = False # # Begin in-band signalling for call end. This has nothign to do with routing traffic directly. @@ -2087,7 +2116,7 @@ if __name__ == '__main__': for system in CONFIG['SYSTEMS']: if CONFIG['SYSTEMS'][system]['ENABLED']: if CONFIG['SYSTEMS'][system]['MODE'] == 'XLXPEER': - logger.warning('(GLOBAL) system %s not started - XLXPEER and PEER connections currently unsupported ', system) + logger.warning('(GLOBAL) system %s not started - XLXPEER connections currently unsupported ', system) continue if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE': systems[system] = routerOBP(system, CONFIG, report_server) From eb4028d7d057ab9bc4c56da88b855bf7e0a7819e Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 16 Apr 2021 23:13:19 +0100 Subject: [PATCH 19/39] LoopControl on PEER, XLXPEER and MASTER connections --- bridge_master.py | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index d76a1f7..ebfcd30 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1315,19 +1315,19 @@ class routerOBP(OPENBRIDGE): #Duplicate handling# #Duplicate complete packet if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: - logger.warning("(%s) *DupControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) return #Handle inbound duplicates if _seq and _seq == self.STATUS[_stream_id]['lastSeq']: - logger.warning("(%s) *DupControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound out-of-order packets if _seq and self.STATUS[_stream_id]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_stream_id]['lastSeq']): - logger.warning("%s) *DupControl* Out of order packet - last sequence number %s, this sequence number %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound missed packets if _seq and self.STATUS[_stream_id]['lastSeq'] and _seq > (self.STATUS[_stream_id]['lastSeq']+1): - logger.warning("(%s) *DupControl* Missed packet - last sequence number %s, this sequence number %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) #Save this sequence number self.STATUS[_stream_id]['lastSeq'] = _seq @@ -1769,23 +1769,49 @@ class routerHBP(HBSYSTEM): if int_id(_dst_id) >= 5 and int_id(_dst_id) != 9 and (str(int_id(_dst_id)) not in BRIDGES): logger.info('(%s) Bridge for TG %s does not exist. Creating as User Activated. Timeout %s',self._system, int_id(_dst_id),CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER']) make_single_bridge(_dst_id,self._system,_slot,CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER']) - + + #LoopControl# + for system in systems: + if system == self._system: + continue + if CONFIG['SYSTEMS'][system]['MODE'] != 'OPENBRIDGE': + for _sysslot in systems[system].STATUS: + if 'RX_STREAM_ID' in systems[system].STATUS[_sysslot] and _stream_id == systems[system].STATUS[_sysslot]['RX_STREAM_ID']: + if 'LOOPLOG' not in self.STATUS[_slot] or not self.STATUS[_slot]['LOOPLOG']: + logger.warning("(%s) OBP *LoopControl* FIRST HBP: %s, STREAM ID: %s, TG: %s, TS: %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id),_sysslot) + self.STATUS[_slot]['LOOPLOG'] = True + self.STATUS[_slot]['LAST'] = pkt_time + return + else: + #if _stream_id in systems[system].STATUS and systems[system].STATUS[_stream_id]['START'] <= self.STATUS[_stream_id]['START']: + if _stream_id in systems[system].STATUS and '1ST' in systems[system].STATUS[_stream_id] and systems[system].STATUS[_stream_id]['TGID'] == _dst_id: + if 'LOOPLOG' not in self.STATUS[_slot] or not self.STATUS[_slot]['LOOPLOG']: + logger.warning("(%s) OBP *LoopControl* FIRST OBP %s, STREAM ID: %s, TG %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id)) + self.STATUS[_slot]['LOOPLOG'] = True + self.STATUS[_slot]['LAST'] = pkt_time + + if CONFIG['SYSTEMS'][self._system]['ENHANCED_OBP'] and '_bcsq' not in self.STATUS[_slot]: + systems[self._system].send_bcsq(_dst_id,_stream_id) + #logger.warning("(%s) OBP *BridgeControl* Sent BCSQ , STREAM ID: %s, TG %s",self._system, int_id(_stream_id), int_id(_dst_id)) + self.STATUS[_slot]['_bcsq'] = True + return + #Duplicate handling# #Duplicate complete packet if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: - logger.warning("(%s) *DupControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) return #Handle inbound duplicates if _seq and _seq == self.STATUS[_slot]['lastSeq']: - logger.warning("(%s) *DupControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound out-of-order packets if _seq and self.STATUS[_slot]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_slot]['lastSeq']): - logger.warning("%s) *DupControl* Out of order packet - last sequence number %s, this sequence number %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound missed packets if _seq and self.STATUS[_slot]['lastSeq'] and _seq > (self.STATUS[_slot]['lastSeq']+1): - logger.warning("(%s) *DupControl* Missed packet - last sequence number %s, this sequence number %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) #Save this sequence number self.STATUS[_slot]['lastSeq'] = _seq From 7632384d5c15b7bbd01601136945a7c1e88c14e8 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 11:05:18 +0100 Subject: [PATCH 20/39] Remove rogue print(() statement that was used for testing --- bridge_master.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index ebfcd30..c60ff9b 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1259,7 +1259,6 @@ class routerOBP(OPENBRIDGE): 'lastData': False } - print(self.STATUS[_stream_id]) # If we can, use the LC from the voice header as to keep all options intact if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD: From cf3a0613ecf499f007314046af92e7af64ff3806 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 12:49:03 +0100 Subject: [PATCH 21/39] Add description to log on login of system --- hblink.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hblink.py b/hblink.py index a3243d0..6e82f0b 100755 --- a/hblink.py +++ b/hblink.py @@ -589,7 +589,7 @@ class HBSYSTEM(DatagramProtocol): _this_peer['PACKAGE_ID'] = _data[262:302] self.send_peer(_peer_id, b''.join([RPTACK, _peer_id])) - logger.info('(%s) Peer %s (%s) has sent repeater configuration, Package ID: %s, Software ID: %s', self._system, _this_peer['CALLSIGN'], _this_peer['RADIO_ID'],self._peers[_peer_id]['PACKAGE_ID'].decode().rstrip(),self._peers[_peer_id]['SOFTWARE_ID'].decode().rstrip()) + logger.info('(%s) Peer %s (%s) has sent repeater configuration, Package ID: %s, Software ID: %s, Desc: %s', self._system, _this_peer['CALLSIGN'], _this_peer['RADIO_ID'],self._peers[_peer_id]['PACKAGE_ID'].decode().rstrip(),self._peers[_peer_id]['SOFTWARE_ID'].decode().rstrip(),self._peers[_peer_id]['DESCRIPTION'].decode().rstrip()) else: self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr) logger.warning('(%s) Peer info from Radio ID that has not logged in: %s', self._system, int_id(_peer_id)) From ad1906f5e23cc96700268d2690a6e16ec432c2d5 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:12:15 +0100 Subject: [PATCH 22/39] _seq does not appear to be an integer for peers --- bridge_master.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index c60ff9b..965071f 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1795,25 +1795,26 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['_bcsq'] = True return + _int_seq == int(_seq.decode()) #Duplicate handling# #Duplicate complete packet - if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: + if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _int_seq > 1: logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) return #Handle inbound duplicates - if _seq and _seq == self.STATUS[_slot]['lastSeq']: - logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) + if _int_seq and _int_seq == self.STATUS[_slot]['lastSeq']: + logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_int_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound out-of-order packets - if _seq and self.STATUS[_slot]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_slot]['lastSeq']): - logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + if _int_seq and self.STATUS[_slot]['lastSeq'] and (_int_seq != 1) and (_int_seq < self.STATUS[_slot]['lastSeq']): + logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_int_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound missed packets - if _seq and self.STATUS[_slot]['lastSeq'] and _seq > (self.STATUS[_slot]['lastSeq']+1): - logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + if _int_seq and self.STATUS[_slot]['lastSeq'] and _int_seq > (self.STATUS[_slot]['lastSeq']+1): + logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_int_seq,int_id(_stream_id),int_id(_dst_id)) #Save this sequence number - self.STATUS[_slot]['lastSeq'] = _seq + self.STATUS[_slot]['lastSeq'] = _int_seq #Save this packet self.STATUS[_slot]['lastData'] = _data From ba77eb5af8187d6cd680bd95577189a0ba937831 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:25:54 +0100 Subject: [PATCH 23/39] Fix --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 965071f..da783cc 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1795,7 +1795,7 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['_bcsq'] = True return - _int_seq == int(_seq.decode()) + _int_seq = int(_seq) #Duplicate handling# #Duplicate complete packet if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _int_seq > 1: From 6e970c28b436faed1848db8eb711345201354c6e Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:44:19 +0100 Subject: [PATCH 24/39] Revert "Fix" This reverts commit ba77eb5af8187d6cd680bd95577189a0ba937831. --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index da783cc..965071f 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1795,7 +1795,7 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['_bcsq'] = True return - _int_seq = int(_seq) + _int_seq == int(_seq.decode()) #Duplicate handling# #Duplicate complete packet if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _int_seq > 1: From 1da0b9731455696e9e4ac8e63e40be6226bfa0db Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:44:20 +0100 Subject: [PATCH 25/39] Revert "_seq does not appear to be an integer for peers" This reverts commit ad1906f5e23cc96700268d2690a6e16ec432c2d5. --- bridge_master.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 965071f..c60ff9b 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1795,26 +1795,25 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['_bcsq'] = True return - _int_seq == int(_seq.decode()) #Duplicate handling# #Duplicate complete packet - if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _int_seq > 1: + if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) return #Handle inbound duplicates - if _int_seq and _int_seq == self.STATUS[_slot]['lastSeq']: - logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_int_seq,int_id(_stream_id),int_id(_dst_id)) + if _seq and _seq == self.STATUS[_slot]['lastSeq']: + logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound out-of-order packets - if _int_seq and self.STATUS[_slot]['lastSeq'] and (_int_seq != 1) and (_int_seq < self.STATUS[_slot]['lastSeq']): - logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_int_seq,int_id(_stream_id),int_id(_dst_id)) + if _seq and self.STATUS[_slot]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_slot]['lastSeq']): + logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) return #Inbound missed packets - if _int_seq and self.STATUS[_slot]['lastSeq'] and _int_seq > (self.STATUS[_slot]['lastSeq']+1): - logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_int_seq,int_id(_stream_id),int_id(_dst_id)) + if _seq and self.STATUS[_slot]['lastSeq'] and _seq > (self.STATUS[_slot]['lastSeq']+1): + logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) #Save this sequence number - self.STATUS[_slot]['lastSeq'] = _int_seq + self.STATUS[_slot]['lastSeq'] = _seq #Save this packet self.STATUS[_slot]['lastData'] = _data From f3c0d084bdade4db5e03417d821fbf71df190941 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:45:40 +0100 Subject: [PATCH 26/39] ok --- bridge_master.py | 5 +++++ hblink.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index c60ff9b..e0b5730 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1795,6 +1795,11 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['_bcsq'] = True return +<<<<<<< Updated upstream +======= + _int_seq = _seq.decode() + _int_seq = int(_int_seq) +>>>>>>> Stashed changes #Duplicate handling# #Duplicate complete packet if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: diff --git a/hblink.py b/hblink.py index 6e82f0b..7ebd81b 100755 --- a/hblink.py +++ b/hblink.py @@ -636,7 +636,7 @@ class HBSYSTEM(DatagramProtocol): _peer_id = _data[11:15] if self._config['LOOSE'] or _peer_id == self._config['RADIO_ID']: # Validate the Radio_ID unless using loose validation - _seq = _data[4:5] + _seq = int(_data[4:5]) _rf_src = _data[5:8] _dst_id = _data[8:11] _bits = _data[15] From fa7ccf6fd748c005d5523a10e1ca1e2ce28f6799 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:46:28 +0100 Subject: [PATCH 27/39] ged --- bridge_master.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bridge_master.py b/bridge_master.py index e0b5730..94f1330 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1796,6 +1796,11 @@ class routerHBP(HBSYSTEM): return <<<<<<< Updated upstream +<<<<<<< Updated upstream +======= + _int_seq = _seq.decode() + _int_seq = int(_int_seq) +>>>>>>> Stashed changes ======= _int_seq = _seq.decode() _int_seq = int(_int_seq) From 9d398ee6f7803397b858b71d00af976488ef3fba Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:46:46 +0100 Subject: [PATCH 28/39] frog --- bridge_master.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bridge_master.py b/bridge_master.py index 94f1330..57fe0c3 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1797,6 +1797,11 @@ class routerHBP(HBSYSTEM): <<<<<<< Updated upstream <<<<<<< Updated upstream +<<<<<<< Updated upstream +======= + _int_seq = _seq.decode() + _int_seq = int(_int_seq) +>>>>>>> Stashed changes ======= _int_seq = _seq.decode() _int_seq = int(_int_seq) From ca1fc469ecfa8c51bf27b3e2d7587ab1f56e6dc7 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:47:53 +0100 Subject: [PATCH 29/39] finally --- bridge_master.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 57fe0c3..5a03f4e 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1794,22 +1794,8 @@ class routerHBP(HBSYSTEM): #logger.warning("(%s) OBP *BridgeControl* Sent BCSQ , STREAM ID: %s, TG %s",self._system, int_id(_stream_id), int_id(_dst_id)) self.STATUS[_slot]['_bcsq'] = True return - -<<<<<<< Updated upstream -<<<<<<< Updated upstream -<<<<<<< Updated upstream -======= - _int_seq = _seq.decode() - _int_seq = int(_int_seq) ->>>>>>> Stashed changes -======= - _int_seq = _seq.decode() - _int_seq = int(_int_seq) ->>>>>>> Stashed changes -======= - _int_seq = _seq.decode() - _int_seq = int(_int_seq) ->>>>>>> Stashed changes + + _int_seq = int(_seq) #Duplicate handling# #Duplicate complete packet if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: From a41a6d1a41c5842dffb5c9cc496df0ea51e1f0ff Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:48:30 +0100 Subject: [PATCH 30/39] try again --- bridge_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge_master.py b/bridge_master.py index 5a03f4e..0dbdcc8 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1795,7 +1795,7 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['_bcsq'] = True return - _int_seq = int(_seq) + _int_seq = _seq #Duplicate handling# #Duplicate complete packet if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: From aac52a03a5ad17fc4b4de83b446337c6bf28b5e3 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 15:55:30 +0100 Subject: [PATCH 31/39] Try only 4 --- hblink.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hblink.py b/hblink.py index 7ebd81b..299ce0b 100755 --- a/hblink.py +++ b/hblink.py @@ -636,7 +636,8 @@ class HBSYSTEM(DatagramProtocol): _peer_id = _data[11:15] if self._config['LOOSE'] or _peer_id == self._config['RADIO_ID']: # Validate the Radio_ID unless using loose validation - _seq = int(_data[4:5]) + #_seq = _data[4:5] + _seq = _data[4] _rf_src = _data[5:8] _dst_id = _data[8:11] _bits = _data[15] From d0df2469d6adbacf0ce2f3d8c6cb8b68005acb1b Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 17 Apr 2021 17:59:46 +0100 Subject: [PATCH 32/39] Stop people creating TG bridges for TG 4000 and 5000 --- bridge_master.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 0dbdcc8..60e642b 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -1765,7 +1765,7 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['RX_LC'] = LC_OPT + _dst_id + _rf_src #Create default bridge for unknown TG - if int_id(_dst_id) >= 5 and int_id(_dst_id) != 9 and (str(int_id(_dst_id)) not in BRIDGES): + if int_id(_dst_id) >= 5 and int_id(_dst_id) != 9 and int_id(_dst_id) != 4000 and int_id(_dst_id) != 5000 and (str(int_id(_dst_id)) not in BRIDGES): logger.info('(%s) Bridge for TG %s does not exist. Creating as User Activated. Timeout %s',self._system, int_id(_dst_id),CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER']) make_single_bridge(_dst_id,self._system,_slot,CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER']) @@ -1795,7 +1795,6 @@ class routerHBP(HBSYSTEM): self.STATUS[_slot]['_bcsq'] = True return - _int_seq = _seq #Duplicate handling# #Duplicate complete packet if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: From e9c0fc42988b8e932d0b93eeb63f7a2dee436394 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 20 Apr 2021 15:55:02 +0100 Subject: [PATCH 33/39] Change local TG limit from < 89 to < 79 --- bridge_master.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index 60e642b..32873af 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -179,7 +179,7 @@ def make_single_bridge(_tgid,_sourcesystem,_slot,_tmout): BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()}) BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 2, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()}) - if _system[0:3] == 'OBP' and int_id(_tgid) >= 89: + if _system[0:3] == 'OBP' and int_id(_tgid) >= 79: BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': True,'TIMEOUT': '','TO_TYPE': 'NONE','OFF': [],'ON': [],'RESET': [], 'TIMER': time()}) #Make static bridge - used for on-the-fly relay bridges @@ -265,7 +265,7 @@ def make_single_reflector(_tgid,_tmout,_sourcesystem): BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': True,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time() + (_tmout * 60)}) else: BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER'] * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()}) - if _system[0:3] == 'OBP' and int_id(_tgid) >= 89: + if _system[0:3] == 'OBP' and int_id(_tgid) >= 79: BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': True,'TIMEOUT': '','TO_TYPE': 'NONE','OFF': [],'ON': [],'RESET': [], 'TIMER': time()}) def remove_bridge_system(system): From 7549664be7405aab0538e29c6a21cda1de7c3006 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 20 Apr 2021 17:21:22 +0100 Subject: [PATCH 34/39] Update bridge.py with proper dup handling --- bridge.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/bridge.py b/bridge.py index 48a3487..413d3e0 100755 --- a/bridge.py +++ b/bridge.py @@ -213,18 +213,6 @@ class routerOBP(OPENBRIDGE): pkt_time = time() dmrpkt = _data[20:53] _bits = _data[15] - - #Handle inbound duplicates - if _seq == True and _seq == self._lastSeq: - logger.debug("%s) Duplicate sequence number %s, disgarding",self._system,_seq) - return - #Inbound out-of-order packets - elif _seq == True and (_seq != 1) and (_seq < self._lastSeq): - logger.debug("%s) Out of order packet - last sequence number %s, this sequence number %s, disgarding",self._system,self._lastSeq,_seq) - return - #Inbound missed packets - elif _seq == True and _seq > (self._lastSeq+1): - logger.debug("(%s) Missed packet - last sequence number %s, this sequence number %s",self._system,self._lastSeq,_seq) if _call_type == 'group': # Is this a new call stream? @@ -252,6 +240,28 @@ class routerOBP(OPENBRIDGE): self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot) if CONFIG['REPORTS']['REPORT']: self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore')) + + #Duplicate handling# + #Duplicate complete packet + if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: + logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) + return + #Handle inbound duplicates + if _seq and _seq == self.STATUS[_stream_id]['lastSeq']: + logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) + return + #Inbound out-of-order packets + if _seq and self.STATUS[_stream_id]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_stream_id]['lastSeq']): + logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + return + #Inbound missed packets + if _seq and self.STATUS[_stream_id]['lastSeq'] and _seq > (self.STATUS[_stream_id]['lastSeq']+1): + logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + + #Save this sequence number + self.STATUS[_stream_id]['lastSeq'] = _seq + #Save this packet + self.STATUS[_stream_id]['lastData'] = _data self.STATUS[_stream_id]['LAST'] = pkt_time From 20e52808d5444818dcd901dd59722d52bf44a11a Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 20 Apr 2021 17:28:32 +0100 Subject: [PATCH 35/39] Else --- bridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge.py b/bridge.py index 413d3e0..3fb9fb1 100755 --- a/bridge.py +++ b/bridge.py @@ -240,7 +240,7 @@ class routerOBP(OPENBRIDGE): self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot) if CONFIG['REPORTS']['REPORT']: self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore')) - + else: #Duplicate handling# #Duplicate complete packet if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: From 35b109250416395f818f435a62d07cfe0ae5a325 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 20 Apr 2021 17:29:54 +0100 Subject: [PATCH 36/39] Lastdata --- bridge.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bridge.py b/bridge.py index 3fb9fb1..ec7aab7 100755 --- a/bridge.py +++ b/bridge.py @@ -223,6 +223,8 @@ class routerOBP(OPENBRIDGE): 'CONTENTION':False, 'RFS': _rf_src, 'TGID': _dst_id, + 'lastSeq': False, + 'lastData': False } # If we can, use the LC from the voice header as to keep all options intact From da55a4ec63677b186f34a7824b6da425bdb4a4a2 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 20 Apr 2021 23:18:19 +0100 Subject: [PATCH 37/39] Finished stream detection for bridge.py --- bridge.py | 77 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/bridge.py b/bridge.py index ec7aab7..7b4da59 100755 --- a/bridge.py +++ b/bridge.py @@ -148,7 +148,7 @@ def rule_timer_loop(): report_server.send_clients(b'bridge updated') -# run this every 10 seconds to trim orphaned stream ids +## run this every 10 seconds to trim orphaned stream ids def stream_trimmer_loop(): logger.debug('(ROUTER) Trimming inactive stream IDs from system lists') _now = time() @@ -166,6 +166,9 @@ def stream_trimmer_loop(): system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_RFS']), int_id(_slot['RX_TGID']), slot, _slot['RX_TIME'] - _slot['RX_START']) if CONFIG['REPORTS']['REPORT']: systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_PEER']), int_id(_slot['RX_RFS']), slot, int_id(_slot['RX_TGID']), _slot['RX_TIME'] - _slot['RX_START']).encode(encoding='utf-8', errors='ignore')) + #Null stream_id - for loop control + if _slot['RX_TIME'] < _now - 60: + _slot['RX_STREAM_ID'] = b'\x00' # TX slot check if _slot['TX_TYPE'] != HBPF_SLT_VTERM and _slot['TX_TIME'] < _now - 5: @@ -179,23 +182,60 @@ def stream_trimmer_loop(): # We can't delete items from a dicationry that's being iterated, so we have to make a temporarly list of entrys to remove later if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE': remove_list = [] + fin_list = [] for stream_id in systems[system].STATUS: - try: - if systems[system].STATUS[stream_id]['LAST'] < _now - 5: - remove_list.append(stream_id) - except: - logger.debug("(%s) Keyerror - stream trimmer Stream ID: %s Start: %s Contention: %s RFS: %s TGID: %s",stream_id,systems[system].STATUS[stream_id]['START'],systems[system].STATUS[stream_id]['CONTENTION'],systems[system].STATUS[stream_id]['RFS'],int_id(systems[system].STATUS[stream_id]['TGID'])) - systems[system].STATUS[stream_id]['LAST'] = _now + + #if stream already marked as finished, just remove it + if '_fin' in systems[system].STATUS[stream_id] and systems[system].STATUS[stream_id]['LAST'] < _now - 180: + logger.info('(%s) *FINISHED STREAM* STREAM ID: %s',system, int_id(stream_id)) + fin_list.append(stream_id) continue - for stream_id in remove_list: - if stream_id in systems[system].STATUS: + + #try: + if '_to' not in systems[system].STATUS[stream_id] and '_fin' not in systems[system].STATUS[stream_id] and systems[system].STATUS[stream_id]['LAST'] < _now - 5: _stream = systems[system].STATUS[stream_id] _sysconfig = CONFIG['SYSTEMS'][system] + #systems[system].STATUS[stream_id]['_fin'] = True logger.info('(%s) *TIME OUT* STREAM ID: %s SUB: %s PEER: %s TGID: %s TS 1 Duration: %.2f', \ system, int_id(stream_id), get_alias(int_id(_stream['RFS']), subscriber_ids), get_alias(int_id(_sysconfig['NETWORK_ID']), peer_ids), get_alias(int_id(_stream['TGID']), talkgroup_ids), _stream['LAST'] - _stream['START']) if CONFIG['REPORTS']['REPORT']: systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(stream_id), int_id(_sysconfig['NETWORK_ID']), int_id(_stream['RFS']), 1, int_id(_stream['TGID']), _stream['LAST'] - _stream['START']).encode(encoding='utf-8', errors='ignore')) + systems[system].STATUS[stream_id]['_to'] = True + continue + #except: + #logger.warning("(%s) Keyerror - stream trimmer Stream ID: %s",system,stream_id) + #systems[system].STATUS[stream_id]['LAST'] = _now + #continue + + + try: + if systems[system].STATUS[stream_id]['LAST'] < _now - 180: + remove_list.append(stream_id) + except: + logger.warning("(%s) Keyerror - stream trimmer Stream ID: %s",system,stream_id) + systems[system].STATUS[stream_id]['LAST'] = _now + continue + + #remove finished + for stream_id in fin_list: + removed = systems[system].STATUS.pop(stream_id) + + for stream_id in remove_list: + if stream_id in systems[system].STATUS: + _stream = systems[system].STATUS[stream_id] + _sysconfig = CONFIG['SYSTEMS'][system] + removed = systems[system].STATUS.pop(stream_id) + + try: + _bcsq_remove = [] + for tgid in _sysconfig['_bcsq']: + if _sysconfig['_bcsq'][tgid] == stream_id: + _bcsq_remove.append(tgid) + for bcrm in _bcsq_remove: + removed = _sysconfig['_bcsq'].pop(bcrm) + except KeyError: + pass else: logger.error('(%s) Attemped to remove OpenBridge Stream ID %s not in the Stream ID list: %s', system, int_id(stream_id), [id for id in systems[system].STATUS]) @@ -242,7 +282,15 @@ class routerOBP(OPENBRIDGE): self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot) if CONFIG['REPORTS']['REPORT']: self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore')) - else: + else: + + #Finished stream handling# + if '_fin' in self.STATUS[_stream_id]: + if '_finlog' not in self.STATUS[_stream_id]: + logger.warning("(%s) OBP *LoopControl* STREAM ID: %s ALREADY FINISHED FROM THIS SOURCE, IGNORING",self._system, int_id(_stream_id)) + self.STATUS[_stream_id]['_finlog'] = True + return + #Duplicate handling# #Duplicate complete packet if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: @@ -420,10 +468,11 @@ class routerOBP(OPENBRIDGE): self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration) if CONFIG['REPORTS']['REPORT']: self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration).encode(encoding='utf-8', errors='ignore')) - removed = self.STATUS.pop(_stream_id) - logger.debug('(%s) OpenBridge sourced call stream end, remove terminated Stream ID: %s', self._system, int_id(_stream_id)) - if not removed: - selflogger.error('(%s) *CALL END* STREAM ID: %s NOT IN LIST -- THIS IS A REAL PROBLEM', self._system, int_id(_stream_id)) + self.STATUS[_stream_id]['_fin'] = True + #removed = self.STATUS.pop(_stream_id) + #logger.debug('(%s) OpenBridge sourced call stream end, remove terminated Stream ID: %s', self._system, int_id(_stream_id)) + #if not removed: + #selflogger.error('(%s) *CALL END* STREAM ID: %s NOT IN LIST -- THIS IS A REAL PROBLEM', self._system, int_id(_stream_id)) #Reset sequence number self._lastSeq = False From 932468a1c7d92d978cd946296e6f5d02e8cf482c Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 20 Apr 2021 23:24:21 +0100 Subject: [PATCH 38/39] Loop control for OBP in bridge.py --- bridge.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/bridge.py b/bridge.py index 7b4da59..9012936 100755 --- a/bridge.py +++ b/bridge.py @@ -291,6 +291,33 @@ class routerOBP(OPENBRIDGE): self.STATUS[_stream_id]['_finlog'] = True return + #LoopControl# + for system in systems: + if system == self._system: + continue + if CONFIG['SYSTEMS'][system]['MODE'] != 'OPENBRIDGE': + for _sysslot in systems[system].STATUS: + if 'RX_STREAM_ID' in systems[system].STATUS[_sysslot] and _stream_id == systems[system].STATUS[_sysslot]['RX_STREAM_ID']: + if 'LOOPLOG' not in self.STATUS[_stream_id] or not self.STATUS[_stream_id]['LOOPLOG']: + logger.warning("(%s) OBP *LoopControl* FIRST HBP: %s, STREAM ID: %s, TG: %s, TS: %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id),_sysslot) + self.STATUS[_stream_id]['LOOPLOG'] = True + self.STATUS[_stream_id]['LAST'] = pkt_time + return + else: + #if _stream_id in systems[system].STATUS and systems[system].STATUS[_stream_id]['START'] <= self.STATUS[_stream_id]['START']: + if _stream_id in systems[system].STATUS and '1ST' in systems[system].STATUS[_stream_id] and systems[system].STATUS[_stream_id]['TGID'] == _dst_id: + if 'LOOPLOG' not in self.STATUS[_stream_id] or not self.STATUS[_stream_id]['LOOPLOG']: + logger.warning("(%s) OBP *LoopControl* FIRST OBP %s, STREAM ID: %s, TG %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id)) + self.STATUS[_stream_id]['LOOPLOG'] = True + self.STATUS[_stream_id]['LAST'] = pkt_time + + if CONFIG['SYSTEMS'][self._system]['ENHANCED_OBP'] and '_bcsq' not in self.STATUS[_stream_id]: + systems[self._system].send_bcsq(_dst_id,_stream_id) + #logger.warning("(%s) OBP *BridgeControl* Sent BCSQ , STREAM ID: %s, TG %s",self._system, int_id(_stream_id), int_id(_dst_id)) + self.STATUS[_stream_id]['_bcsq'] = True + return + + #Duplicate handling# #Duplicate complete packet if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1: From 80b80e78544e363f4ac4ed55a7fac279f0c44554 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 20 Apr 2021 23:29:44 +0100 Subject: [PATCH 39/39] LoopNDup for HBP derived connections in bridge.py --- bridge.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/bridge.py b/bridge.py index 9012936..7cb6d04 100755 --- a/bridge.py +++ b/bridge.py @@ -537,7 +537,10 @@ class routerHBP(HBSYSTEM): 2: b'\x00', 3: b'\x00', 4: b'\x00', - } + }, + 'lastSeq': False, + 'lastData': False + }, 2: { 'RX_START': time(), @@ -563,7 +566,9 @@ class routerHBP(HBSYSTEM): 2: b'\x00', 3: b'\x00', 4: b'\x00', - } + }, + 'lastSeq': False, + 'lastData': False } } @@ -597,6 +602,56 @@ class routerHBP(HBSYSTEM): else: self.STATUS[_slot]['RX_LC'] = LC_OPT + _dst_id + _rf_src + #LoopControl# + for system in systems: + if system == self._system: + continue + if CONFIG['SYSTEMS'][system]['MODE'] != 'OPENBRIDGE': + for _sysslot in systems[system].STATUS: + if 'RX_STREAM_ID' in systems[system].STATUS[_sysslot] and _stream_id == systems[system].STATUS[_sysslot]['RX_STREAM_ID']: + if 'LOOPLOG' not in self.STATUS[_slot] or not self.STATUS[_slot]['LOOPLOG']: + logger.warning("(%s) OBP *LoopControl* FIRST HBP: %s, STREAM ID: %s, TG: %s, TS: %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id),_sysslot) + self.STATUS[_slot]['LOOPLOG'] = True + self.STATUS[_slot]['LAST'] = pkt_time + return + else: + #if _stream_id in systems[system].STATUS and systems[system].STATUS[_stream_id]['START'] <= self.STATUS[_stream_id]['START']: + if _stream_id in systems[system].STATUS and '1ST' in systems[system].STATUS[_stream_id] and systems[system].STATUS[_stream_id]['TGID'] == _dst_id: + if 'LOOPLOG' not in self.STATUS[_slot] or not self.STATUS[_slot]['LOOPLOG']: + logger.warning("(%s) OBP *LoopControl* FIRST OBP %s, STREAM ID: %s, TG %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id)) + self.STATUS[_slot]['LOOPLOG'] = True + self.STATUS[_slot]['LAST'] = pkt_time + + if CONFIG['SYSTEMS'][self._system]['ENHANCED_OBP'] and '_bcsq' not in self.STATUS[_slot]: + systems[self._system].send_bcsq(_dst_id,_stream_id) + #logger.warning("(%s) OBP *BridgeControl* Sent BCSQ , STREAM ID: %s, TG %s",self._system, int_id(_stream_id), int_id(_dst_id)) + self.STATUS[_slot]['_bcsq'] = True + return + + #Duplicate handling# + #Duplicate complete packet + if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1: + logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) + return + #Handle inbound duplicates + if _seq and _seq == self.STATUS[_slot]['lastSeq']: + logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id)) + return + #Inbound out-of-order packets + if _seq and self.STATUS[_slot]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_slot]['lastSeq']): + logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + return + #Inbound missed packets + if _seq and self.STATUS[_slot]['lastSeq'] and _seq > (self.STATUS[_slot]['lastSeq']+1): + logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id)) + + #Save this sequence number + self.STATUS[_slot]['lastSeq'] = _seq + #Save this packet + self.STATUS[_slot]['lastData'] = _data + + + for _bridge in BRIDGES: for _system in BRIDGES[_bridge]: