mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
#1641 DMR Hytera RRS packet support.
This commit is contained in:
@@ -80,6 +80,7 @@ import io.github.dsheirer.module.decode.dmr.message.voice.embedded.EncryptionPar
|
||||
import io.github.dsheirer.module.decode.event.DecodeEvent;
|
||||
import io.github.dsheirer.module.decode.event.DecodeEventType;
|
||||
import io.github.dsheirer.module.decode.event.PlottableDecodeEvent;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.rrs.HyteraRrsPacket;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraUnknownPacket;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.shortdata.HyteraShortDataPacket;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sms.HyteraSmsPacket;
|
||||
@@ -325,7 +326,22 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
.build();
|
||||
broadcast(smsEvent);
|
||||
}
|
||||
//Hytera Short Data - Radio Registration Service (RRS)
|
||||
//Hytera Radio Registration Service (RRS)
|
||||
else if(packet.getPacket() instanceof HyteraRrsPacket rrs)
|
||||
{
|
||||
MutableIdentifierCollection mic = new MutableIdentifierCollection(packet.getIdentifiers());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("HYTERA RRS REGISTER RADIO:");
|
||||
sb.append(rrs.getDestination());
|
||||
DecodeEvent shortDataEvent = DMRDecodeEvent.builder(DecodeEventType.RADIO_REGISTRATION_SERVICE, packet.getTimestamp())
|
||||
.identifiers(mic)
|
||||
.timeslot(getTimeslot())
|
||||
.details(sb.toString())
|
||||
.build();
|
||||
broadcast(shortDataEvent);
|
||||
}
|
||||
//Hytera Short Data
|
||||
else if(packet.getPacket() instanceof HyteraShortDataPacket hsdp)
|
||||
{
|
||||
MutableIdentifierCollection mic = new MutableIdentifierCollection(packet.getIdentifiers());
|
||||
@@ -343,7 +359,6 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
|
||||
sb.append(" SHORT DATA:").append(hsdp.getMessage().toHexString());
|
||||
|
||||
|
||||
DecodeEvent shortDataEvent = DMRDecodeEvent.builder(DecodeEventType.RADIO_REGISTRATION_SERVICE, packet.getTimestamp())
|
||||
.identifiers(mic)
|
||||
.timeslot(getTimeslot())
|
||||
|
||||
@@ -34,6 +34,7 @@ import io.github.dsheirer.module.decode.dmr.message.type.DataPacketFormat;
|
||||
import io.github.dsheirer.module.decode.dmr.message.type.ServiceAccessPoint;
|
||||
import io.github.dsheirer.module.decode.ip.DefinedShortDataPacket;
|
||||
import io.github.dsheirer.module.decode.ip.UnknownPacket;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.rrs.HyteraRrsPacket;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraTokenHeader;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraUnknownPacket;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.shortdata.HyteraShortDataPacket;
|
||||
@@ -243,8 +244,19 @@ public class PacketSequenceMessageFactory
|
||||
*/
|
||||
public static IMessage createDefinedShortData(PacketSequence packetSequence, CorrectedBinaryMessage packet)
|
||||
{
|
||||
return new DMRPacketMessage(packetSequence, new DefinedShortDataPacket(packet, 0), packet,
|
||||
packetSequence.getTimeslot(), packetSequence.getPacketSequenceHeader().getTimestamp());
|
||||
//Test to see if this is Hytera Radio Registration Service (RRS)
|
||||
HyteraTokenHeader hyteraTokenHeader = new HyteraTokenHeader(packet);
|
||||
|
||||
if(hyteraTokenHeader.isRRSMessage())
|
||||
{
|
||||
return new DMRPacketMessage(packetSequence, new HyteraRrsPacket(hyteraTokenHeader), packet,
|
||||
packetSequence.getTimeslot(), packetSequence.getPacketSequenceHeader().getTimestamp());
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DMRPacketMessage(packetSequence, new DefinedShortDataPacket(packet, 0), packet,
|
||||
packetSequence.getTimeslot(), packetSequence.getPacketSequenceHeader().getTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 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.module.decode.ip.hytera.rrs;
|
||||
|
||||
import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.module.decode.dmr.identifier.DMRRadio;
|
||||
import io.github.dsheirer.module.decode.ip.IPacket;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sds.DestinationId;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraToken;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraTokenHeader;
|
||||
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraTokenType;
|
||||
import io.github.dsheirer.module.decode.p25.identifier.ipv4.DMRIpAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Hytera SDS Long Data Message with SMS encoded payload
|
||||
*/
|
||||
public class HyteraRrsPacket implements IPacket
|
||||
{
|
||||
private HyteraTokenHeader mHeader;
|
||||
private Identifier mDestination;
|
||||
private List<Identifier> mIdentifiers;
|
||||
|
||||
/**
|
||||
* Constructs a parser for a header contained within a binary message starting at the offset.
|
||||
*
|
||||
* @param header to the packet within the message
|
||||
*/
|
||||
public HyteraRrsPacket(HyteraTokenHeader header)
|
||||
{
|
||||
mHeader = header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("HYTERA RRS REGISTER");
|
||||
if(hasDestination())
|
||||
{
|
||||
sb.append(" RADIO:").append(getDestination());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HyteraTokenHeader getHeader()
|
||||
{
|
||||
return mHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destination radio identifier for the SMS message
|
||||
*/
|
||||
public Identifier getDestination()
|
||||
{
|
||||
if(mDestination == null)
|
||||
{
|
||||
HyteraToken destinationToken = getHeader().getTokenByType(HyteraTokenType.ID_DESTINATION);
|
||||
|
||||
if(destinationToken instanceof DestinationId destinationId)
|
||||
{
|
||||
if(((DestinationId) destinationToken).isIp())
|
||||
{
|
||||
mDestination = DMRIpAddress.createFrom(((DestinationId) destinationToken).getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
mDestination = DMRRadio.createTo(destinationId.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mDestination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the SMS message has a destination identifier
|
||||
*/
|
||||
public boolean hasDestination()
|
||||
{
|
||||
return getDestination() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Identifier> getIdentifiers()
|
||||
{
|
||||
if(mIdentifiers == null)
|
||||
{
|
||||
mIdentifiers = new ArrayList<>();
|
||||
if(hasDestination())
|
||||
{
|
||||
mIdentifiers.add(getDestination());
|
||||
}
|
||||
}
|
||||
|
||||
return mIdentifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPacket getPayload()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPayload()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
package io.github.dsheirer.module.decode.ip.hytera.sds;
|
||||
|
||||
import io.github.dsheirer.bits.CorrectedBinaryMessage;
|
||||
import io.github.dsheirer.identifier.ipv4.IPV4Address;
|
||||
|
||||
/**
|
||||
* Destination Identifier
|
||||
@@ -45,10 +46,19 @@ public class DestinationId extends HyteraToken
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("DESTINATION:").append(getId());
|
||||
sb.append("DESTINATION:").append(getIdFormatted());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this is an IP address (true) or a Radio ID (false).
|
||||
* @return true if IP
|
||||
*/
|
||||
public boolean isIp()
|
||||
{
|
||||
return getId() > 0x00FFFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the content field in bytes.
|
||||
* @return content field length.
|
||||
@@ -69,6 +79,18 @@ public class DestinationId extends HyteraToken
|
||||
return mMessage.getInt(ID);
|
||||
}
|
||||
|
||||
public String getIdFormatted()
|
||||
{
|
||||
if(isIp())
|
||||
{
|
||||
return new IPV4Address(getId()).toString() + " [" + (getId() & 0xFFFFFF) + "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.valueOf(getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
HyteraTokenType getTokenType()
|
||||
{
|
||||
|
||||
@@ -37,11 +37,13 @@ public class HyteraTokenFactory
|
||||
return switch(token)
|
||||
{
|
||||
case ID_DESTINATION -> new DestinationId(message);
|
||||
case ENCODING -> new Encoding(message);
|
||||
case ID_MESSAGE -> new MessageId(message);
|
||||
case PAYLOAD -> new Payload(message);
|
||||
case MESSAGE_HEADER -> new MessageHeader(message);
|
||||
case ID_SOURCE -> new SourceId(message);
|
||||
case ENCODING -> new Encoding(message);
|
||||
case PAYLOAD -> new Payload(message);
|
||||
case RRS_UNKNOWN -> new RrsUnknown(message);
|
||||
case TEXT_MESSAGE_SERVICE_HEADER -> new TmsMessageHeader(message);
|
||||
case RADIO_REGISTRATION_SERVICE_HEADER -> new RrsMessageHeader(message);
|
||||
default -> new Unknown(message);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,7 +72,15 @@ public class HyteraTokenHeader implements IHeader
|
||||
*/
|
||||
public boolean isSMSMessage()
|
||||
{
|
||||
return hasTokens(HyteraTokenType.MESSAGE_HEADER, HyteraTokenType.ENCODING, HyteraTokenType.PAYLOAD);
|
||||
return hasTokens(HyteraTokenType.TEXT_MESSAGE_SERVICE_HEADER, HyteraTokenType.ENCODING, HyteraTokenType.PAYLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this header has RRS service message.
|
||||
*/
|
||||
public boolean isRRSMessage()
|
||||
{
|
||||
return hasTokens(HyteraTokenType.RADIO_REGISTRATION_SERVICE_HEADER, HyteraTokenType.ID_DESTINATION);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +161,7 @@ public class HyteraTokenHeader implements IHeader
|
||||
length += contentLength * 8; //Actual content
|
||||
}
|
||||
|
||||
HyteraToken field = HyteraTokenFactory.getField(token, mMessage.getSubMessage(offset, offset + length + 1));
|
||||
HyteraToken field = HyteraTokenFactory.getField(token, mMessage.getSubMessage(offset, offset + length));
|
||||
offset += length;
|
||||
mParsedTokens.add(field);
|
||||
}
|
||||
|
||||
@@ -29,13 +29,15 @@ package io.github.dsheirer.module.decode.ip.hytera.sds;
|
||||
*/
|
||||
public enum HyteraTokenType
|
||||
{
|
||||
//Note: this may be the message type, but is definitely followed by 4-byte total length field. Need more examples
|
||||
MESSAGE_HEADER(0x0201, 4), //First 2 bytes are total message length, 2nd 2 bytes = unknown
|
||||
RADIO_REGISTRATION_SERVICE_HEADER(0x0200, 1), //Total message length
|
||||
TEXT_MESSAGE_SERVICE_HEADER(0x0201, 4), //First 2 bytes are total message length, 2nd 2 bytes = unknown
|
||||
|
||||
ID_MESSAGE(0x0001, -1),
|
||||
ID_SOURCE(0x0002, -1),
|
||||
ID_DESTINATION(0x0003, -1),
|
||||
ENCODING(0x0101, -1),
|
||||
PAYLOAD(0x0102, -1),
|
||||
RRS_UNKNOWN(0x0703, 0),
|
||||
UNKNOWN(-1, -1);
|
||||
|
||||
private int mOpcode;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 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.module.decode.ip.hytera.sds;
|
||||
|
||||
import io.github.dsheirer.bits.CorrectedBinaryMessage;
|
||||
|
||||
/**
|
||||
* Radio Registration Service (RRS) Message Header
|
||||
*/
|
||||
public class RrsMessageHeader extends HyteraToken
|
||||
{
|
||||
private static int[] MESSAGE_LENGTH_BCD_TENS = new int[]{16, 17, 18, 19};
|
||||
private static int[] MESSAGE_LENGTH_BCD_ONES = new int[]{20, 21, 22, 23};
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
*
|
||||
* @param message containing both the token, run-length, and content
|
||||
*/
|
||||
public RrsMessageHeader(CorrectedBinaryMessage message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("RRS HEADER LENGTH:").append(getMessageLength());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
HyteraTokenType getTokenType()
|
||||
{
|
||||
return HyteraTokenType.RADIO_REGISTRATION_SERVICE_HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overall message length in bytes
|
||||
* @return message length.
|
||||
*/
|
||||
public int getMessageLength()
|
||||
{
|
||||
int length = mMessage.getInt(MESSAGE_LENGTH_BCD_TENS) * 10;
|
||||
length += mMessage.getInt(MESSAGE_LENGTH_BCD_ONES);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 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.module.decode.ip.hytera.sds;
|
||||
|
||||
import io.github.dsheirer.bits.CorrectedBinaryMessage;
|
||||
|
||||
/**
|
||||
* Unknown RRS field parsed from a Hytera Radio Registration Service (RRS) message
|
||||
*/
|
||||
public class RrsUnknown extends HyteraToken
|
||||
{
|
||||
/**
|
||||
* Constructs an instance
|
||||
*
|
||||
* @param message containing both the token, run-length, and content
|
||||
*/
|
||||
public RrsUnknown(CorrectedBinaryMessage message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "RRS UNKNOWN TOKEN";
|
||||
}
|
||||
|
||||
@Override
|
||||
HyteraTokenType getTokenType()
|
||||
{
|
||||
return HyteraTokenType.RRS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -22,16 +22,19 @@ package io.github.dsheirer.module.decode.ip.hytera.sds;
|
||||
import io.github.dsheirer.bits.CorrectedBinaryMessage;
|
||||
|
||||
/**
|
||||
* Message Header
|
||||
*
|
||||
* Text Message Service (TMS) Message Header
|
||||
* <p>
|
||||
* Initial token that specifies the overall message length and some other unidentified bit fields.
|
||||
*
|
||||
* <p>
|
||||
* Note: I've only confirmed this is the start token for long SMS messages, but it may also be the start token for
|
||||
* other packet data messages like GPS or any other packet overlay application.
|
||||
*/
|
||||
public class MessageHeader extends HyteraToken
|
||||
public class TmsMessageHeader extends HyteraToken
|
||||
{
|
||||
private static int[] MESSAGE_LENGTH = new int[]{16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||
private static int[] MESSAGE_LENGTH_BCD_THOUSANDS = new int[]{16, 17, 18, 19};
|
||||
private static int[] MESSAGE_LENGTH_BCD_HUNDREDS = new int[]{20, 21, 22, 23};
|
||||
private static int[] MESSAGE_LENGTH_BCD_TENS = new int[]{24, 25, 26, 27};
|
||||
private static int[] MESSAGE_LENGTH_BCD_ONES = new int[]{28, 29, 30, 31};
|
||||
private static int[] MESSAGE_FLAGS = new int[]{32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||
|
||||
/**
|
||||
@@ -39,7 +42,7 @@ public class MessageHeader extends HyteraToken
|
||||
*
|
||||
* @param message containing both the token, run-length, and content
|
||||
*/
|
||||
public MessageHeader(CorrectedBinaryMessage message)
|
||||
public TmsMessageHeader(CorrectedBinaryMessage message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
@@ -56,7 +59,7 @@ public class MessageHeader extends HyteraToken
|
||||
@Override
|
||||
HyteraTokenType getTokenType()
|
||||
{
|
||||
return HyteraTokenType.MESSAGE_HEADER;
|
||||
return HyteraTokenType.TEXT_MESSAGE_SERVICE_HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,6 +68,7 @@ public class MessageHeader extends HyteraToken
|
||||
* - Priority/Flash (boolean)
|
||||
* - Encryption Type (enum of at least 4 values, ie 2+ bits)
|
||||
* - Emergency (boolean)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getFlags()
|
||||
@@ -78,6 +82,10 @@ public class MessageHeader extends HyteraToken
|
||||
*/
|
||||
public int getMessageLength()
|
||||
{
|
||||
return mMessage.getInt(MESSAGE_LENGTH);
|
||||
int length = mMessage.getInt(MESSAGE_LENGTH_BCD_THOUSANDS) * 1000;
|
||||
length += mMessage.getInt(MESSAGE_LENGTH_BCD_HUNDREDS) * 100;
|
||||
length += mMessage.getInt(MESSAGE_LENGTH_BCD_TENS) * 10;
|
||||
length += mMessage.getInt(MESSAGE_LENGTH_BCD_ONES);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 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.module.decode.p25.identifier.ipv4;
|
||||
|
||||
import io.github.dsheirer.identifier.Role;
|
||||
import io.github.dsheirer.identifier.ipv4.IPV4Address;
|
||||
import io.github.dsheirer.identifier.ipv4.IPV4Identifier;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
|
||||
/**
|
||||
* DMR IPV4 Address
|
||||
*/
|
||||
public class DMRIpAddress extends IPV4Identifier
|
||||
{
|
||||
public DMRIpAddress(IPV4Address ipAddress, Role role)
|
||||
{
|
||||
super(ipAddress, role);
|
||||
}
|
||||
|
||||
public Protocol getProtocol()
|
||||
{
|
||||
return Protocol.DMR;
|
||||
}
|
||||
|
||||
public static DMRIpAddress createTo(int value)
|
||||
{
|
||||
return new DMRIpAddress(new IPV4Address(value), Role.TO);
|
||||
}
|
||||
|
||||
public static DMRIpAddress createFrom(int value)
|
||||
{
|
||||
return new DMRIpAddress(new IPV4Address(value), Role.FROM);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user