Skip to content

#1304 P25 TDMA CC Support & Phase 1/2 decoder enhancements. #1898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .idea/dictionaries/denny.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions src/main/java/io/github/dsheirer/alias/AliasList.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -663,11 +663,13 @@ public TalkgroupAliasList()

public Alias getAlias(TalkgroupIdentifier identifier)
{
//Attempt to do a fully qualified identifier match first.
if(identifier instanceof FullyQualifiedTalkgroupIdentifier fqti)
{
return mFullyQualifiedTalkgroupAliasMap.get(fqti.toString());
return mFullyQualifiedTalkgroupAliasMap.get(fqti.getFullyQualifiedTalkgroupAddress());
}

//Then try to match it by it's locally assigned (temporary) address.
int value = identifier.getValue();

Alias mapValue = mTalkgroupAliasMap.get(value);
Expand All @@ -676,6 +678,7 @@ public Alias getAlias(TalkgroupIdentifier identifier)
return mapValue;
}

//Finally, match the locally assigned address against any talkgroup ranges
for(Map.Entry<TalkgroupRange, Alias> entry : mTalkgroupRangeAliasMap.entrySet())
{
if(entry.getKey().contains(value))
Expand Down Expand Up @@ -780,11 +783,13 @@ public RadioAliasList()

public Alias getAlias(RadioIdentifier identifier)
{
//Attempt to do a fully qualified identifier match first.
if(identifier instanceof FullyQualifiedRadioIdentifier fqri)
{
return mFullyQualifiedRadioAliasMap.get(fqri.toString());
return mFullyQualifiedRadioAliasMap.get(fqri.getFullyQualifiedRadioAddress());
}

//Then match against the locally assigned (temporary) address
int value = identifier.getValue();

Alias mapValue = mRadioAliasMap.get(value);
Expand All @@ -793,6 +798,7 @@ public Alias getAlias(RadioIdentifier identifier)
return mapValue;
}

//Finally, attempt to match the locally assigned (temporary) address against any radio ranges.
for(Map.Entry<RadioRange, Alias> entry : mRadioRangeAliasMap.entrySet())
{
if(entry.getKey().contains(value))
Expand Down
211 changes: 210 additions & 1 deletion src/main/java/io/github/dsheirer/bits/BinaryMessage.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -451,6 +451,203 @@ public int getInt(int[] bits)
return value;
}

/**
* Returns the integer value of the message field described by the field argument.
* @param intField with start and end indices (inclusive).
* @return integer field value.
*/
public int getInt(IntField intField)
{
int value = 0;

for(int index = intField.start(); index <= intField.end(); index++)
{
value = Integer.rotateLeft(value, 1);

if(get(index))
{
value++;
}
}

return value;
}

/**
* Returns the integer value of the message field described by the field argument.
* @param fragmentedField with an array of message indices
* @return integer field value.
*/
public int getInt(FragmentedIntField fragmentedField)
{
int value = 0;

for(int index: fragmentedField.indices())
{
value = Integer.rotateLeft(value, 1);

if(get(index))
{
value++;
}
}

return value;
}

/**
* Indicates if the message field contains a non-zero value indicated by any bits set in the int field indices.
* @param intField to inspect
* @return true if any of the bits are set, indicating a non-zero value.
*/
public boolean hasInt(IntField intField)
{
return nextSetBit(intField.start()) <= intField.end();
}

/**
* Indicates if the message field contains a non-zero value indicated by any bits set in the int field indices.
* @param intField to inspect
* @return true if any of the bits are set, indicating a non-zero value.
*/
public boolean hasInt(FragmentedIntField fragmentedField)
{
for(int index: fragmentedField.indices())
{
if(get(index))
{
return true;
}
}

return false;
}

/**
* Returns the integer value of the message field described by the field argument where the message start index is
* offset within this binary message.
* @param intField with start and end indices (inclusive).
* @param offset to the start of the first message index.
* @return integer field value.
*/
public int getInt(IntField intField, int offset)
{
int value = 0;

for(int index = intField.start() + offset; index <= intField.end() + offset; index++)
{
value = Integer.rotateLeft(value, 1);

if(get(index))
{
value++;
}
}

return value;
}

/**
* Returns the integer value of the message field described by the field argument where the message start index is
* offset within this binary message.
* @param fragmentedField with an array of field indices
* @param offset to the start of the first message index.
* @return integer field value.
*/
public int getInt(FragmentedIntField fragmentedField, int offset)
{
int value = 0;

for(int index: fragmentedField.indices())
{
value = Integer.rotateLeft(value, 1);

if(get(index + offset))
{
value++;
}
}

return value;
}

/**
* Indicates if the message field contains a non-zero value indicated by any bits set in the int field indices.
* @param intField to inspect
* @param offset to the first bit of the message.
* @return true if any of the bits are set, indicating a non-zero value.
*/
public boolean hasInt(IntField intField, int offset)
{
return nextSetBit(intField.start() + offset) <= (intField.end() + offset);
}

/**
* Indicates if the message field contains a non-zero value indicated by any bits set in the int field indices.
* @param intField to inspect
* @param offset to the first bit of the message.
* @return true if any of the bits are set, indicating a non-zero value.
*/
public boolean hasInt(FragmentedIntField fragmentedField, int offset)
{
for(int index: fragmentedField.indices())
{
if(get(index + offset))
{
return true;
}
}

return false;
}

/**
* Returns the long value of the message field described by the field argument.
* @param intField with start and end indices (inclusive).
* @return integer field value.
*/
public long getLong(LongField intField)
{
long value = 0;

for(int index = intField.start(); index <= intField.end(); index++)
{
value = Long.rotateLeft(value, 1);

if(get(index))
{
value++;
}
}

return value;
}

/**
* Returns the long value of the message field described by the field argument where the message start index is
* offset within this binary message.
* @param intField with start and end indices (inclusive).
* @param offset to the start of the first message index.
* @return field value.
*/
public long getLong(LongField intField, int offset)
{
long value = 0;

for(int index = intField.start() + offset; index <= intField.end() + offset; index++)
{
value = Long.rotateLeft(value, 1);

if(get(index))
{
value++;
}
}

return value;
}


/**
* Returns the integer value represented by the bit array
*
Expand Down Expand Up @@ -742,6 +939,18 @@ public String getHex(int start, int end)
return sb.toString();
}

/**
* Returns the integer field formatted as a hex value using zero prefixes to pad the hex character count to fully
* represent the size (width) of the field.
* @param field to parse as hex
* @return hex value.
*/
public String getHex(IntField field)
{
int width = Math.ceilDiv(field.width(), 4);
return String.format("%0" + width + "X", getInt(field));
}

/**
* Format the byte value that starts at the specified index as hexadecimal. If the length of the message is less
* than the start index plus 7 bits, then the value represents those bits as high-order bits with zero padding in
Expand Down
35 changes: 16 additions & 19 deletions src/main/java/io/github/dsheirer/bits/CorrectedBinaryMessage.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 Dennis Sheirer
* *
* * This program is free software: you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * This program is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with this program. If not, see <http://www.gnu.org/licenses/>
* * *****************************************************************************
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.bits;

Expand Down Expand Up @@ -84,9 +81,9 @@ public void incrementCorrectedBitCount(int additionalCount)
/**
* Returns a new binary message containing the bits from (inclusive) to end (exclusive).
*
* @param start bit
* @param end bit
* @return message
* @param start bit inclusive
* @param end bit exclusive
* @return message with sub message bits
*/
public CorrectedBinaryMessage getSubMessage(int start, int end)
{
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/io/github/dsheirer/bits/FragmentedIntField.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/

package io.github.dsheirer.bits;

/**
* Defines a fragmented or non-contiguous bit field within a binary message.
* @param indices for the bits in the field.
*/
public record FragmentedIntField(int... indices)
{
public FragmentedIntField
{
if(indices.length > 32)
{
throw new IllegalArgumentException("Integer field indices size [" + indices.length + "] cannot exceed 32-bits for an integer");
}
}

/**
* Utility constructor method.
* @param indices (inclusive)
* @return constructed fragmented integer field.
*/
public static FragmentedIntField of(int... indices)
{
return new FragmentedIntField(indices);
}
}
Loading