mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-15 01:57:39 -05:00
#1666 P25 Motorola unit self-reported GPS location parsing and plotting to map.
This commit is contained in:
@@ -57,6 +57,7 @@ import io.github.dsheirer.module.decode.p25.phase1.message.P25Message;
|
|||||||
import io.github.dsheirer.module.decode.p25.phase1.message.hdu.HDUMessage;
|
import io.github.dsheirer.module.decode.p25.phase1.message.hdu.HDUMessage;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.hdu.HeaderData;
|
import io.github.dsheirer.module.decode.p25.phase1.message.hdu.HeaderData;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.LinkControlWord;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.LinkControlWord;
|
||||||
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaUnitGPS;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCCallTermination;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCCallTermination;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCExtendedFunctionCommand;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCExtendedFunctionCommand;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCMessageUpdate;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCMessageUpdate;
|
||||||
@@ -1885,6 +1886,22 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList
|
|||||||
case UNIT_TO_UNIT_ANSWER_REQUEST:
|
case UNIT_TO_UNIT_ANSWER_REQUEST:
|
||||||
processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.PAGE, "Unit-to-Unit Answer Request");
|
processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.PAGE, "Unit-to-Unit Answer Request");
|
||||||
break;
|
break;
|
||||||
|
case MOTOROLA_UNIT_GPS:
|
||||||
|
if(lcw instanceof LCMotorolaUnitGPS moto)
|
||||||
|
{
|
||||||
|
String gpsDetails = "LOCATION: " + moto.getLatitude() + " " + moto.getLongitude();
|
||||||
|
|
||||||
|
PlottableDecodeEvent event = PlottableDecodeEvent.plottableBuilder(DecodeEventType.GPS, timestamp)
|
||||||
|
.location(new GeoPosition(moto.getLatitude(), moto.getLongitude()))
|
||||||
|
.channel(getCurrentChannel())
|
||||||
|
.details(gpsDetails)
|
||||||
|
.end(timestamp)
|
||||||
|
.protocol(Protocol.APCO25)
|
||||||
|
.identifiers(new IdentifierCollection(getIdentifierCollection().getIdentifiers()))
|
||||||
|
.build();
|
||||||
|
broadcast(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// mLog.debug("Unrecognized LCW Opcode: " + lcw.getOpcode().name() + " VENDOR:" + lcw.getVendor() +
|
// mLog.debug("Unrecognized LCW Opcode: " + lcw.getOpcode().name() + " VENDOR:" + lcw.getVendor() +
|
||||||
// " OPCODE:" + lcw.getOpcodeNumber());
|
// " OPCODE:" + lcw.getOpcodeNumber());
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ public enum LinkControlOpcode
|
|||||||
MOTOROLA_PATCH_GROUP_VOICE_CHANNEL_UPDATE("PATCH GROUP VOICE CHANNEL UPDATE", 1),
|
MOTOROLA_PATCH_GROUP_VOICE_CHANNEL_UPDATE("PATCH GROUP VOICE CHANNEL UPDATE", 1),
|
||||||
MOTOROLA_PATCH_GROUP_ADD("PATCH GROUP ADD", 3),
|
MOTOROLA_PATCH_GROUP_ADD("PATCH GROUP ADD", 3),
|
||||||
MOTOROLA_PATCH_GROUP_DELETE("PATCH GROUP DELETE", 4),
|
MOTOROLA_PATCH_GROUP_DELETE("PATCH GROUP DELETE", 4),
|
||||||
|
MOTOROLA_UNIT_GPS("UNIT GPS", 6),
|
||||||
MOTOROLA_TALK_COMPLETE("TALK_COMPLETE", 15),
|
MOTOROLA_TALK_COMPLETE("TALK_COMPLETE", 15),
|
||||||
MOTOROLA_UNKNOWN("UNKNOWN", -1),
|
MOTOROLA_UNKNOWN("UNKNOWN", -1),
|
||||||
|
|
||||||
@@ -201,6 +202,8 @@ public enum LinkControlOpcode
|
|||||||
return MOTOROLA_PATCH_GROUP_ADD;
|
return MOTOROLA_PATCH_GROUP_ADD;
|
||||||
case 4:
|
case 4:
|
||||||
return MOTOROLA_PATCH_GROUP_DELETE;
|
return MOTOROLA_PATCH_GROUP_DELETE;
|
||||||
|
case 6:
|
||||||
|
return MOTOROLA_UNIT_GPS;
|
||||||
case 15:
|
case 15:
|
||||||
return MOTOROLA_TALK_COMPLETE;
|
return MOTOROLA_TALK_COMPLETE;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* *****************************************************************************
|
||||||
* sdrtrunk
|
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||||
* Copyright (C) 2014-2019 Dennis Sheirer
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
* *****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.dsheirer.module.decode.p25.phase1.message.lc;
|
package io.github.dsheirer.module.decode.p25.phase1.message.lc;
|
||||||
@@ -26,6 +25,7 @@ import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorol
|
|||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaPatchGroupVoiceChannelUpdate;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaPatchGroupVoiceChannelUpdate;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaPatchGroupVoiceChannelUser;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaPatchGroupVoiceChannelUser;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaTalkComplete;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaTalkComplete;
|
||||||
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaUnitGPS;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaUnknownOpcode;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola.LCMotorolaUnknownOpcode;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCAdjacentSiteStatusBroadcast;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCAdjacentSiteStatusBroadcast;
|
||||||
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCAdjacentSiteStatusBroadcastExplicit;
|
import io.github.dsheirer.module.decode.p25.phase1.message.lc.standard.LCAdjacentSiteStatusBroadcastExplicit;
|
||||||
@@ -138,6 +138,8 @@ public class LinkControlWordFactory
|
|||||||
return new LCMotorolaTalkComplete(binaryMessage);
|
return new LCMotorolaTalkComplete(binaryMessage);
|
||||||
case MOTOROLA_PATCH_GROUP_VOICE_CHANNEL_UPDATE:
|
case MOTOROLA_PATCH_GROUP_VOICE_CHANNEL_UPDATE:
|
||||||
return new LCMotorolaPatchGroupVoiceChannelUpdate(binaryMessage);
|
return new LCMotorolaPatchGroupVoiceChannelUpdate(binaryMessage);
|
||||||
|
case MOTOROLA_UNIT_GPS:
|
||||||
|
return new LCMotorolaUnitGPS(binaryMessage);
|
||||||
case MOTOROLA_UNKNOWN:
|
case MOTOROLA_UNKNOWN:
|
||||||
return new LCMotorolaUnknownOpcode(binaryMessage);
|
return new LCMotorolaUnknownOpcode(binaryMessage);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* 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.phase1.message.lc.motorola;
|
||||||
|
|
||||||
|
import io.github.dsheirer.bits.BinaryMessage;
|
||||||
|
import io.github.dsheirer.identifier.Identifier;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Motorola Unit Self-Reported GPS Location
|
||||||
|
*/
|
||||||
|
public class LCMotorolaUnitGPS extends MotorolaLinkControlWord
|
||||||
|
{
|
||||||
|
private static final double LATITUDE_MULTIPLIER = 90.0 / 0x7FFFFF;
|
||||||
|
private static final double LONGITUDE_MULTIPLIER = 180.0 / 0x7FFFFF;
|
||||||
|
|
||||||
|
private static final int[] UNKNOWN = {16, 17, 18, 19, 20, 21, 22, 23};
|
||||||
|
private static final int LATITUDE_SIGN = 24;
|
||||||
|
private static final int[] LATITUDE = {25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||||
|
private static final int LONGITUDE_SIGN = 48;
|
||||||
|
private static final int[] LONGITUDE = {49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance
|
||||||
|
* @param message binary
|
||||||
|
*/
|
||||||
|
public LCMotorolaUnitGPS(BinaryMessage message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("MOTOROLA UNIT GPS LOCATION: ").append(getLatitude()).append(" ").append(getLongitude());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPS Latitude value.
|
||||||
|
* @return value in decimal degrees
|
||||||
|
*/
|
||||||
|
public double getLatitude()
|
||||||
|
{
|
||||||
|
return getMessage().getInt(LATITUDE) * LATITUDE_MULTIPLIER * (getMessage().get(LATITUDE_SIGN) ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPS Longitude value.
|
||||||
|
* @return value in decimal degrees
|
||||||
|
*/
|
||||||
|
public double getLongitude()
|
||||||
|
{
|
||||||
|
return getMessage().getInt(LONGITUDE) * LONGITUDE_MULTIPLIER * (getMessage().get(LONGITUDE_SIGN) ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of identifiers contained in this message
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Identifier> getIdentifiers()
|
||||||
|
{
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user