Adds support for Motorola Opcode 07 Deny Response message. (#482)

This commit is contained in:
Denny Sheirer
2019-01-12 04:42:52 -05:00
committed by GitHub
parent 85ca66f656
commit 4ab37735e8
5 changed files with 256 additions and 57 deletions

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 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
@@ -84,6 +84,7 @@ import io.github.dsheirer.module.decode.p25.message.pdu.packet.sndcp.SNDCPPacket
import io.github.dsheirer.module.decode.p25.message.pdu.umbtc.isp.UMBTCTelephoneInterconnectRequestExplicitDialing;
import io.github.dsheirer.module.decode.p25.message.tdu.TDULinkControlMessage;
import io.github.dsheirer.module.decode.p25.message.tsbk.TSBKMessage;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.MotorolaDenyResponse;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.PatchGroupVoiceChannelGrant;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.PatchGroupVoiceChannelGrantUpdate;
import io.github.dsheirer.module.decode.p25.message.tsbk.standard.isp.CancelServiceRequest;
@@ -2134,9 +2135,22 @@ public class P25DecoderState extends DecoderState implements IChannelEventListen
.identifiers(icRoaming)
.build());
break;
case MOTOROLA_OSP_OPCODE_7:
mLog.info("MOTOROLA OPCODE 7: " + tsbk.getMessage().toHexString());
break;
case MOTOROLA_OSP_DENY_RESPONSE:
if(tsbk instanceof MotorolaDenyResponse)
{
MotorolaDenyResponse dr = (MotorolaDenyResponse)tsbk;
MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers());
ic.remove(IdentifierClass.USER);
ic.update(tsbk.getIdentifiers());
broadcast(P25DecodeEvent.builder(tsbk.getTimestamp())
.channel(getCurrentChannel())
.eventDescription(DecodeEventType.RESPONSE.toString())
.details("DENY: " + dr.getDeniedServiceType().getDescription() +
" REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo())
.identifiers(ic)
.build());
}
default:
// mLog.debug("Unrecognized TSBK Opcode: " + tsbk.getOpcode().name() + " VENDOR:" + tsbk.getVendor() +
// " OPCODE:" + tsbk.getOpcodeNumber());

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 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
@@ -170,7 +170,7 @@ public enum Opcode
MOTOROLA_OSP_PATCH_GROUP_CHANNEL_GRANT(2, "PTCH GRP VCHN GR", "MOTOROLA PATCH GROUP CHANNEL GRANT"),
MOTOROLA_OSP_PATCH_GROUP_CHANNEL_GRANT_UPDATE(3, "PTCH GRP VCH UPD", "MOTOROLA PATCH GROUP CHANNEL GRANT UPDATE"),
MOTOROLA_OSP_TRAFFIC_CHANNEL_ID(5, "CHANNEL CWID", "CHANNEL CWID"),
MOTOROLA_OSP_OPCODE_7(7, "MOTOROLA OPCODE 7", "MOTOROLA OPCODE 07"),
MOTOROLA_OSP_DENY_RESPONSE(7, "DENY RESPONSE", "MOTOROLA DENY RESPONSE"),
MOTOROLA_OSP_SYSTEM_LOADING(9, "SYSTEM LOADING", "SYSTEM LOADING"),
MOTOROLA_OSP_CONTROL_CHANNEL_ID(11, "CCH BASE STAT ID", "CONTROL CHANNEL BASE STATION ID"),
MOTOROLA_OSP_CONTROL_CHANNEL_PLANNED_SHUTDOWN(14, "CCH PLND SHUTDWN", "CONTROL CHANNEL PLANNED SHUTDOWN"),
@@ -294,7 +294,7 @@ public enum Opcode
case 0x05:
return MOTOROLA_OSP_TRAFFIC_CHANNEL_ID;
case 0x07:
return MOTOROLA_OSP_OPCODE_7;
return MOTOROLA_OSP_DENY_RESPONSE;
case 0x09:
return MOTOROLA_OSP_SYSTEM_LOADING;
case 0x0B:

View File

@@ -1,3 +1,23 @@
/*
* ******************************************************************************
* sdrtrunk
* 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/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.p25.message.tsbk;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
@@ -6,6 +26,7 @@ import io.github.dsheirer.module.decode.p25.P25Interleave;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.isp.UnknownMotorolaISPMessage;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.ChannelCWID;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.ChannelLoading;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.MotorolaDenyResponse;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.PatchGroupAdd;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.PatchGroupDelete;
import io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp.PatchGroupVoiceChannelGrant;
@@ -270,6 +291,8 @@ public class TSBKMessageFactory
return new ChannelCWID(dataUnitID, message, nac, timestamp);
case MOTOROLA_OSP_CONTROL_CHANNEL_PLANNED_SHUTDOWN:
return new PlannedChannelShutdown(dataUnitID, message, nac, timestamp);
case MOTOROLA_OSP_DENY_RESPONSE:
return new MotorolaDenyResponse(dataUnitID, message, nac, timestamp);
case MOTOROLA_OSP_TRAFFIC_CHANNEL_ID:
return new ChannelCWID(dataUnitID, message, nac, timestamp);
case MOTOROLA_OSP_PATCH_GROUP_ADD:

View File

@@ -0,0 +1,132 @@
/*
* ******************************************************************************
* sdrtrunk
* 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/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.p25.message.tsbk.motorola.osp;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.p25.identifier.talkgroup.APCO25ToTalkgroup;
import io.github.dsheirer.module.decode.p25.message.tsbk.OSPMessage;
import io.github.dsheirer.module.decode.p25.message.tsbk.Opcode;
import io.github.dsheirer.module.decode.p25.reference.DataUnitID;
import io.github.dsheirer.module.decode.p25.reference.DenyReason;
import io.github.dsheirer.module.decode.p25.reference.Direction;
import io.github.dsheirer.module.decode.p25.reference.Vendor;
import java.util.ArrayList;
import java.util.List;
/**
* Deny response
*/
public class MotorolaDenyResponse extends OSPMessage
{
private static final int ADDITIONAL_INFORMATION_FLAG = 16;
private static final int[] SERVICE_TYPE = {18, 19, 20, 21, 22, 23};
private static final int[] REASON = {24, 25, 26, 27, 28, 29, 30, 31};
private static final int[] ADDITIONAL_INFO = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55};
private static final int[] TARGET_ADDRESS = {56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, 79};
private DenyReason mDenyReason;
private String mAdditionalInfo;
private Identifier mTargetAddress;
private List<Identifier> mIdentifiers;
/**
* Constructs a TSBK from the binary message sequence.
*/
public MotorolaDenyResponse(DataUnitID dataUnitId, CorrectedBinaryMessage message, int nac, long timestamp)
{
super(dataUnitId, message, nac, timestamp);
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(getMessageStub());
sb.append(" TO:").append(getTargetAddress());
sb.append(" SERVICE:").append(getDeniedServiceType());
sb.append(" REASON:").append(getDenyReason());
if(hasAdditionalInformation())
{
sb.append(" INFO:").append(getAdditionalInfo());
}
return sb.toString();
}
private boolean hasAdditionalInformation()
{
return getMessage().get(ADDITIONAL_INFORMATION_FLAG);
}
public String getAdditionalInfo()
{
if(mAdditionalInfo == null)
{
mAdditionalInfo = getMessage().getHex(ADDITIONAL_INFO, 6);
}
return mAdditionalInfo;
}
/**
* Opcode representing the service type that is being acknowledged by the radio unit.
*/
public Opcode getDeniedServiceType()
{
return Opcode.fromValue(getMessage().getInt(SERVICE_TYPE), Direction.INBOUND, Vendor.STANDARD);
}
public DenyReason getDenyReason()
{
if(mDenyReason == null)
{
mDenyReason = DenyReason.fromCode(getMessage().getInt(REASON));
}
return mDenyReason;
}
public Identifier getTargetAddress()
{
if(mTargetAddress == null)
{
mTargetAddress = APCO25ToTalkgroup.createIndividual(getMessage().getInt(TARGET_ADDRESS));
}
return mTargetAddress;
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getTargetAddress());
}
return mIdentifiers;
}
}

View File

@@ -1,125 +1,155 @@
/*
* ******************************************************************************
* sdrtrunk
* 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/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.p25.reference;
public enum DenyReason
{
RESERVED( 0x00 ),
REQUESTING_UNIT_NOT_VALID( 0x10 ),
REQUESTING_UNIT_NOT_AUTHORIZED_FOR_SERVICE( 0x11 ),
TARGET_UNIT_NOT_VALID( 0x20 ),
TARGET_UNIT_NOT_AUTHORIZED_FOR_SERVICE( 0x21 ),
TARGET_UNIT_REFUSED_CALL( 0x2F ),
TARGET_GROUP_NOT_VALID( 0x30 ),
TARGET_GROUP_NOT_AUTHORIZED_FOR_SERVICE( 0x31 ),
INVALID_DIALING( 0x40 ),
TELEPHONE_NUMBER_NOT_AUTHORIZED( 0x41 ),
PSTN_NOT_VALID( 0x42 ),
CALL_TIMEOUT( 0x50 ),
LANDLINE_TERMINATED_CALL( 0x51 ),
SUBSCRIBER_UNIT_TERMINATED_CALL( 0x52 ),
CALL_PREEMPTED( 0x5F ),
SITE_ACCESS_DENIAL( 0x60 ),
USER_OR_SYSTEM_DEFINED( 0x61 ),
CALL_OPTIONS_NOT_VALID_FOR_SERVICE( 0xF0 ),
PROTECTION_SERVICE_OPTION_NOT_VALID( 0xF1 ),
DUPLEX_SERVICE_OPTION_NOT_VALID( 0xF2 ),
CIRCUIT_OR_PACKET_MODE_OPTION_NOT_VALID( 0xF3 ),
SYSTEM_DOES_NOT_SUPPORT_SERVICE( 0xFF ),
UNKNOWN( -1 );
RESERVED(0x00),
REQUESTING_UNIT_NOT_VALID(0x10),
REQUESTING_UNIT_NOT_AUTHORIZED_FOR_SERVICE(0x11),
TARGET_UNIT_NOT_VALID(0x20),
TARGET_UNIT_NOT_AUTHORIZED_FOR_SERVICE(0x21),
TARGET_UNIT_REFUSED_CALL(0x2F),
TARGET_GROUP_NOT_VALID(0x30),
TARGET_GROUP_NOT_AUTHORIZED_FOR_SERVICE(0x31),
INVALID_DIALING(0x40),
TELEPHONE_NUMBER_NOT_AUTHORIZED(0x41),
PSTN_NOT_VALID(0x42),
CALL_TIMEOUT(0x50),
LANDLINE_TERMINATED_CALL(0x51),
SUBSCRIBER_UNIT_TERMINATED_CALL(0x52),
CALL_PREEMPTED(0x5F),
SITE_ACCESS_DENIAL(0x60),
USER_OR_SYSTEM_DEFINED(0x61), //0x61 - 0xEF
PTT_COLLIDE(0x67),
PTT_BONK(0x77),
CALL_OPTIONS_NOT_VALID_FOR_SERVICE(0xF0),
PROTECTION_SERVICE_OPTION_NOT_VALID(0xF1),
DUPLEX_SERVICE_OPTION_NOT_VALID(0xF2),
CIRCUIT_OR_PACKET_MODE_OPTION_NOT_VALID(0xF3),
SYSTEM_DOES_NOT_SUPPORT_SERVICE(0xFF),
UNKNOWN(-1);
private int mCode;
private DenyReason( int code )
private DenyReason(int code)
{
mCode = code;
}
public static DenyReason fromCode( int code )
public static DenyReason fromCode(int code)
{
if( code == 0x10 )
if(code == 0x10)
{
return DenyReason.REQUESTING_UNIT_NOT_VALID;
}
else if( code == 0x11 )
else if(code == 0x11)
{
return REQUESTING_UNIT_NOT_AUTHORIZED_FOR_SERVICE;
}
else if( code == 0x20 )
else if(code == 0x20)
{
return DenyReason.TARGET_UNIT_NOT_VALID;
}
else if( code == 0x21 )
else if(code == 0x21)
{
return TARGET_UNIT_NOT_AUTHORIZED_FOR_SERVICE;
}
else if( code == 0x2F )
else if(code == 0x2F)
{
return DenyReason.TARGET_UNIT_REFUSED_CALL;
}
else if( code == 0x30 )
else if(code == 0x30)
{
return TARGET_GROUP_NOT_VALID;
}
else if( code == 0x31 )
else if(code == 0x31)
{
return DenyReason.TARGET_GROUP_NOT_AUTHORIZED_FOR_SERVICE;
}
else if( code == 0x40 )
else if(code == 0x40)
{
return DenyReason.INVALID_DIALING;
}
else if( code == 0x41 )
else if(code == 0x41)
{
return DenyReason.TELEPHONE_NUMBER_NOT_AUTHORIZED;
}
else if( code == 0x42 )
else if(code == 0x42)
{
return DenyReason.PSTN_NOT_VALID;
}
else if( code == 0x50 )
else if(code == 0x50)
{
return CALL_TIMEOUT;
}
else if( code == 0x51 )
else if(code == 0x51)
{
return LANDLINE_TERMINATED_CALL;
}
else if( code == 0x52 )
else if(code == 0x52)
{
return SUBSCRIBER_UNIT_TERMINATED_CALL;
}
else if( code == 0x5F )
else if(code == 0x5F)
{
return DenyReason.CALL_PREEMPTED;
}
else if( code == 0x60 )
else if(code == 0x60)
{
return SITE_ACCESS_DENIAL;
}
else if( code == 0xF0 )
else if(code == 0xF0)
{
return CALL_OPTIONS_NOT_VALID_FOR_SERVICE;
}
else if( code == 0xF1 )
else if(code == 0xF1)
{
return PROTECTION_SERVICE_OPTION_NOT_VALID;
}
else if( code == 0xF2 )
else if(code == 0xF2)
{
return DenyReason.DUPLEX_SERVICE_OPTION_NOT_VALID;
}
else if( code == 0xF3 )
else if(code == 0xF3)
{
return CIRCUIT_OR_PACKET_MODE_OPTION_NOT_VALID;
}
else if( code <= 0x5E )
else if(code == 0x67)
{
return PTT_COLLIDE;
}
else if(code == 0x77)
{
return PTT_BONK;
}
else if(code <= 0x5E)
{
return DenyReason.RESERVED;
}
else if( code >= 0x61 )
else if(code >= 0x61)
{
return DenyReason.USER_OR_SYSTEM_DEFINED;
}
return UNKNOWN;
}
}