fix(dmr): avoid stale and mislabeled talkgroups

This commit is contained in:
2026-07-14 21:30:41 +03:00
parent 7c4b024186
commit fa5a95ca5d
3 changed files with 32 additions and 5 deletions
+26
View File
@@ -166,6 +166,7 @@ type
function GetLastBurst(var Dibits: array of Byte; out Sequence: QWord): Boolean;
class function SyncKindName(Kind: TDMRSyncKind): string; static;
class function LinkControlTargetText(const S: TDMRStatus): string; static;
property Enabled: Boolean read FEnabled;
property OnAudio: TDMRAudioEvent read FOnAudio write FOnAudio;
end;
@@ -580,6 +581,17 @@ begin
FFixedNegativeOuter := 0;
FFixedCenter := 0;
FMobileActiveBurst := True;
// LC belongs to a call/slot, not to the tuned frequency forever. Keeping it
// across carrier loss made a newly acquired call briefly inherit the old
// target and display the same apparent TG on unrelated transmissions.
FillChar(FLinkControl, SizeOf(FLinkControl), 0);
FLastLCSlot := -1;
FSelectedSlot := -1;
FLastSelectedVoiceTick := 0;
FColorCodeValid := False;
FColorCode := 0;
FLastDataType := 0;
FSlotTypeCorrectedBits := 0;
DMRMbeReset(FMbe);
end;
@@ -947,4 +959,18 @@ begin
end;
end;
class function TDMRDecoder.LinkControlTargetText(
const S: TDMRStatus): string;
begin
Result := '';
if not S.LinkControlValid or (S.TargetID = 0) then Exit;
// ETSI Full Link Control opcode 0 is Group Voice Channel User; opcode 3 is
// Unit-to-Unit Voice Channel User. Other/vendor opcodes may reuse these 24
// bits for different data, so do not mislabel them as a talkgroup.
case S.LCOpcode of
0: Result := 'TG' + IntToStr(S.TargetID);
3: Result := 'ID' + IntToStr(S.TargetID);
end;
end;
end.
+3 -2
View File
@@ -3606,7 +3606,7 @@ end;
function TMainForm.DMRStatusText: string;
var
S: TDMRStatus;
Inv, Details: string;
Inv, Details, TargetText: string;
begin
if not FController.GetDMRStatus(S) then Exit('DMR unavailable');
if not S.Enabled then Exit('DMR off');
@@ -3617,7 +3617,8 @@ begin
else if S.CACHValid then Details := Format(' TS%d', [S.Slot + 1]);
if S.SlotTypeValid then
Details := Details + Format(' CC%d/DT%d', [S.ColorCode, S.DataType]);
if S.LinkControlValid then Details := Details + Format(' TG%d', [S.TargetID]);
TargetText := TDMRDecoder.LinkControlTargetText(S);
if TargetText <> '' then Details := Details + ' ' + TargetText;
Result := Format('DMR %s%s%s #%d',
[TDMRDecoder.SyncKindName(S.SyncKind), Details, Inv,
S.SyncCount]);
+3 -3
View File
@@ -1382,7 +1382,7 @@ var
I, Slot: Integer;
O: TVfoOverlay;
S: TDMRStatus;
Txt: string;
Txt, TargetText: string;
begin
if FController = nil then Exit;
for I := 0 to High(FSliceFlags) do
@@ -1401,8 +1401,8 @@ begin
else if S.CACHValid then Slot := S.Slot;
if Slot in [0, 1] then Txt := 'DMR TS' + IntToStr(Slot + 1);
if S.SlotTypeValid then Txt := Txt + ' CC' + IntToStr(S.ColorCode);
if S.LinkControlValid and (S.TargetID <> 0) then
Txt := Txt + ' TG' + IntToStr(S.TargetID);
TargetText := TDMRDecoder.LinkControlTargetText(S);
if TargetText <> '' then Txt := Txt + ' ' + TargetText;
O.UpdateDMRStatus(Txt, True);
end;
end;