From d8bb9c055a3fcc15dfc92ea8238b4c26bf71f55c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 May 2022 16:50:14 -0700 Subject: Configurable API sanitization --- setup/default.xml | 1 + 1 file changed, 1 insertion(+) (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 71e14f501..1f89ae3d8 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -12,6 +12,7 @@ 8082 ./web + true false true -- cgit v1.2.3 From 24197b483c932c473ef14fb8efff4d368b2559fe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 May 2022 15:26:56 -0700 Subject: Update version numbers --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 0b3f54355..25c8a32e3 100644 --- a/build.gradle +++ b/build.gradle @@ -95,7 +95,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "4.15", + "Implementation-Version": "5.0", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 3ffab1289..64137f8d6 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=4.15 +AppVersion=5.0 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index ac0d73d5b..77100dd32 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "4.15", + "version": "5.0", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From ce661ec77a957b70c15509c6801e6f34b32ad11d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 13:12:37 -0700 Subject: Improve dependency injection --- setup/default.xml | 2 - src/main/java/org/traccar/MainModule.java | 213 ++------------------- src/main/java/org/traccar/WebDataHandler.java | 6 +- src/main/java/org/traccar/config/Keys.java | 14 -- .../org/traccar/database/ConnectionManager.java | 9 +- .../traccar/handler/ComputedAttributesHandler.java | 5 +- .../org/traccar/handler/CopyAttributesHandler.java | 30 ++- .../org/traccar/handler/DefaultDataHandler.java | 5 +- .../java/org/traccar/handler/DistanceHandler.java | 4 +- .../org/traccar/handler/EngineHoursHandler.java | 5 +- .../java/org/traccar/handler/FilterHandler.java | 67 +++---- .../org/traccar/handler/HemisphereHandler.java | 5 +- .../java/org/traccar/handler/MotionHandler.java | 12 +- .../org/traccar/handler/RemoteAddressHandler.java | 24 ++- .../org/traccar/handler/SpeedLimitHandler.java | 5 +- src/main/java/org/traccar/handler/TimeHandler.java | 14 +- .../traccar/handler/events/AlertEventHandler.java | 5 +- .../handler/events/BehaviorEventHandler.java | 4 +- .../handler/events/CommandResultEventHandler.java | 8 +- .../traccar/handler/events/DriverEventHandler.java | 5 +- .../handler/events/FuelDropEventHandler.java | 4 +- .../handler/events/GeofenceEventHandler.java | 5 +- .../handler/events/IgnitionEventHandler.java | 5 +- .../handler/events/MaintenanceEventHandler.java | 5 +- .../traccar/handler/events/MotionEventHandler.java | 5 +- .../handler/events/OverspeedEventHandler.java | 5 +- .../org/traccar/reports/model/TripsConfig.java | 47 +---- src/test/java/org/traccar/TestIdentityManager.java | 3 - .../org/traccar/handler/FilterHandlerTest.java | 75 ++++---- .../org/traccar/handler/MotionHandlerTest.java | 7 +- 30 files changed, 232 insertions(+), 371 deletions(-) (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 1f89ae3d8..dea638d7a 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -30,8 +30,6 @@ 86400 true - true - true ./media diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 79cfcc0a8..60b5854fd 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -18,7 +18,10 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.AbstractModule; import com.google.inject.Provides; +import com.google.inject.Scopes; import com.google.inject.Singleton; +import io.netty.util.HashedWheelTimer; +import io.netty.util.Timer; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.AttributesManager; @@ -43,51 +46,35 @@ import org.traccar.geocoder.GoogleGeocoder; import org.traccar.geocoder.HereGeocoder; import org.traccar.geocoder.MapQuestGeocoder; import org.traccar.geocoder.MapTilerGeocoder; +import org.traccar.geocoder.MapboxGeocoder; import org.traccar.geocoder.MapmyIndiaGeocoder; import org.traccar.geocoder.NominatimGeocoder; import org.traccar.geocoder.OpenCageGeocoder; import org.traccar.geocoder.PositionStackGeocoder; import org.traccar.geocoder.TomTomGeocoder; -import org.traccar.geocoder.MapboxGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; import org.traccar.geolocation.OpenCellIdGeolocationProvider; import org.traccar.geolocation.UnwiredGeolocationProvider; -import org.traccar.handler.ComputedAttributesHandler; -import org.traccar.handler.CopyAttributesHandler; -import org.traccar.handler.DefaultDataHandler; -import org.traccar.handler.DistanceHandler; -import org.traccar.handler.EngineHoursHandler; -import org.traccar.handler.FilterHandler; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; -import org.traccar.handler.HemisphereHandler; -import org.traccar.handler.MotionHandler; -import org.traccar.handler.RemoteAddressHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.handler.TimeHandler; -import org.traccar.handler.events.AlertEventHandler; -import org.traccar.handler.events.BehaviorEventHandler; -import org.traccar.handler.events.CommandResultEventHandler; -import org.traccar.handler.events.DriverEventHandler; -import org.traccar.handler.events.FuelDropEventHandler; -import org.traccar.handler.events.GeofenceEventHandler; -import org.traccar.handler.events.IgnitionEventHandler; -import org.traccar.handler.events.MaintenanceEventHandler; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.reports.model.TripsConfig; - -import javax.annotation.Nullable; -import javax.ws.rs.client.Client; -import io.netty.util.Timer; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; +import javax.annotation.Nullable; +import javax.ws.rs.client.Client; + public class MainModule extends AbstractModule { + @Override + protected void configure() { + bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); + } + @Provides public static ObjectMapper provideObjectMapper() { return Context.getObjectMapper(); @@ -153,13 +140,6 @@ public class MainModule extends AbstractModule { return Context.getMaintenancesManager(); } - @Singleton - @Provides - public static StatisticsManager provideStatisticsManager( - Config config, DataManager dataManager, Client client, ObjectMapper objectMapper) { - return new StatisticsManager(config, dataManager, client, objectMapper); - } - @Singleton @Provides public static Geocoder provideGeocoder(Config config) { @@ -249,50 +229,6 @@ public class MainModule extends AbstractModule { return null; } - @Singleton - @Provides - public static DistanceHandler provideDistanceHandler(Config config, IdentityManager identityManager) { - return new DistanceHandler(config, identityManager); - } - - @Singleton - @Provides - public static FilterHandler provideFilterHandler(Config config) { - if (config.getBoolean(Keys.FILTER_ENABLE)) { - return new FilterHandler(config); - } - return null; - } - - @Singleton - @Provides - public static HemisphereHandler provideHemisphereHandler(Config config) { - if (config.hasKey(Keys.LOCATION_LATITUDE_HEMISPHERE) || config.hasKey(Keys.LOCATION_LONGITUDE_HEMISPHERE)) { - return new HemisphereHandler(config); - } - return null; - } - - @Singleton - @Provides - public static RemoteAddressHandler provideRemoteAddressHandler(Config config) { - if (config.getBoolean(Keys.PROCESSING_REMOTE_ADDRESS_ENABLE)) { - return new RemoteAddressHandler(); - } - return null; - } - - @Singleton - @Provides - public static WebDataHandler provideWebDataHandler( - Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) { - if (config.hasKey(Keys.FORWARD_URL)) { - return new WebDataHandler(config, identityManager, objectMapper, client); - } - return null; - } - - @Singleton @Provides public static GeolocationHandler provideGeolocationHandler( Config config, @Nullable GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { @@ -302,7 +238,6 @@ public class MainModule extends AbstractModule { return null; } - @Singleton @Provides public static GeocoderHandler provideGeocoderHandler( Config config, @Nullable Geocoder geocoder, IdentityManager identityManager) { @@ -312,7 +247,6 @@ public class MainModule extends AbstractModule { return null; } - @Singleton @Provides public static SpeedLimitHandler provideSpeedLimitHandler(@Nullable SpeedLimitProvider speedLimitProvider) { if (speedLimitProvider != null) { @@ -321,127 +255,4 @@ public class MainModule extends AbstractModule { return null; } - @Singleton - @Provides - public static MotionHandler provideMotionHandler(TripsConfig tripsConfig) { - return new MotionHandler(tripsConfig.getSpeedThreshold()); - } - - @Singleton - @Provides - public static EngineHoursHandler provideEngineHoursHandler(Config config, IdentityManager identityManager) { - if (config.getBoolean(Keys.PROCESSING_ENGINE_HOURS_ENABLE)) { - return new EngineHoursHandler(identityManager); - } - return null; - } - - @Singleton - @Provides - public static CopyAttributesHandler provideCopyAttributesHandler(Config config, IdentityManager identityManager) { - if (config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE)) { - return new CopyAttributesHandler(identityManager); - } - return null; - } - - @Singleton - @Provides - public static ComputedAttributesHandler provideComputedAttributesHandler( - Config config, IdentityManager identityManager, AttributesManager attributesManager) { - if (config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_ENABLE)) { - return new ComputedAttributesHandler(config, identityManager, attributesManager); - } - return null; - } - - @Singleton - @Provides - public static TimeHandler provideTimeHandler(Config config) { - if (config.hasKey(Keys.TIME_OVERRIDE)) { - return new TimeHandler(config); - } - return null; - } - - @Singleton - @Provides - public static DefaultDataHandler provideDefaultDataHandler(@Nullable DataManager dataManager) { - if (dataManager != null) { - return new DefaultDataHandler(dataManager); - } - return null; - } - - @Singleton - @Provides - public static CommandResultEventHandler provideCommandResultEventHandler() { - return new CommandResultEventHandler(); - } - - @Singleton - @Provides - public static OverspeedEventHandler provideOverspeedEventHandler( - Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { - return new OverspeedEventHandler(config, deviceManager, geofenceManager); - } - - @Singleton - @Provides - public static BehaviorEventHandler provideBehaviorEventHandler(Config config, IdentityManager identityManager) { - return new BehaviorEventHandler(config, identityManager); - } - - @Singleton - @Provides - public static FuelDropEventHandler provideFuelDropEventHandler(IdentityManager identityManager) { - return new FuelDropEventHandler(identityManager); - } - - @Singleton - @Provides - public static MotionEventHandler provideMotionEventHandler( - IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { - return new MotionEventHandler(identityManager, deviceManager, tripsConfig); - } - - @Singleton - @Provides - public static GeofenceEventHandler provideGeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, - ConnectionManager connectionManager) { - return new GeofenceEventHandler(identityManager, geofenceManager, calendarManager, connectionManager); - } - - @Singleton - @Provides - public static AlertEventHandler provideAlertEventHandler(Config config, IdentityManager identityManager) { - return new AlertEventHandler(config, identityManager); - } - - @Singleton - @Provides - public static IgnitionEventHandler provideIgnitionEventHandler(IdentityManager identityManager) { - return new IgnitionEventHandler(identityManager); - } - - @Singleton - @Provides - public static MaintenanceEventHandler provideMaintenanceEventHandler( - IdentityManager identityManager, MaintenancesManager maintenancesManager) { - return new MaintenanceEventHandler(identityManager, maintenancesManager); - } - - @Singleton - @Provides - public static DriverEventHandler provideDriverEventHandler(IdentityManager identityManager) { - return new DriverEventHandler(identityManager); - } - - @Singleton - @Provides - public static Timer provideTimer() { - return GlobalTimer.getTimer(); - } - } diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 678096d34..2c0aa0f8e 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -287,8 +287,10 @@ public class WebDataHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - AsyncRequestAndCallback request = new AsyncRequestAndCallback(position); - request.send(); + if (url != null) { + AsyncRequestAndCallback request = new AsyncRequestAndCallback(position); + request.send(); + } return position; } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index bb3ea393a..eebdf7172 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1021,13 +1021,6 @@ public final class Keys { "processing.remoteAddress.enable", Collections.singletonList(KeyType.GLOBAL)); - /** - * Enable engine hours calculation on the server side. It uses ignition value to determine engine state. - */ - public static final ConfigKey PROCESSING_ENGINE_HOURS_ENABLE = new ConfigKey<>( - "processing.engineHours.enable", - Collections.singletonList(KeyType.GLOBAL)); - /** * Enable copying of missing attributes from last position to the current one. Might be useful if device doesn't * send some values in every message. @@ -1036,13 +1029,6 @@ public final class Keys { "processing.copyAttributes.enable", Collections.singletonList(KeyType.GLOBAL)); - /** - * Enable computed attributes processing. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_ENABLE = new ConfigKey<>( - "processing.computedAttributes.enable", - Collections.singletonList(KeyType.GLOBAL)); - /** * Enable computed attributes processing. */ diff --git a/src/main/java/org/traccar/database/ConnectionManager.java b/src/main/java/org/traccar/database/ConnectionManager.java index 359061f00..f0e40f631 100644 --- a/src/main/java/org/traccar/database/ConnectionManager.java +++ b/src/main/java/org/traccar/database/ConnectionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package org.traccar.database; import io.netty.channel.Channel; import io.netty.util.Timeout; +import io.netty.util.Timer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.GlobalTimer; import org.traccar.Main; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -52,9 +52,12 @@ public class ConnectionManager { private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); + private final Timer timer; + public ConnectionManager() { deviceTimeout = Context.getConfig().getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = Context.getConfig().getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); + timer = Main.getInjector().getInstance(Timer.class); } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { @@ -118,7 +121,7 @@ public class ConnectionManager { } if (status.equals(Device.STATUS_ONLINE)) { - timeouts.put(deviceId, GlobalTimer.getTimer().newTimeout(timeout1 -> { + timeouts.put(deviceId, timer.newTimeout(timeout1 -> { if (!timeout1.isCancelled()) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); } diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 153da29b9..9dc170909 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,6 +40,8 @@ import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class ComputedAttributesHandler extends BaseDataHandler { @@ -52,6 +54,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private final boolean includeDeviceAttributes; + @Inject public ComputedAttributesHandler( Config config, IdentityManager identityManager, AttributesManager attributesManager) { this.identityManager = identityManager; diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index f386116b0..8285dcc5d 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,27 +18,37 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.database.IdentityManager; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class CopyAttributesHandler extends BaseDataHandler { - private IdentityManager identityManager; + private final boolean enabled; + private final IdentityManager identityManager; - public CopyAttributesHandler(IdentityManager identityManager) { + @Inject + public CopyAttributesHandler(Config config, IdentityManager identityManager) { + enabled = config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE); this.identityManager = identityManager; } @Override protected Position handlePosition(Position position) { - String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "processing.copyAttributes", "", false, true); - Position last = identityManager.getLastPosition(position.getDeviceId()); - if (last != null) { - for (String attribute : attributesString.split("[ ,]")) { - if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) { - position.getAttributes().put(attribute, last.getAttributes().get(attribute)); + if (enabled) { + String attributesString = identityManager.lookupAttributeString( + position.getDeviceId(), "processing.copyAttributes", "", false, true); + Position last = identityManager.getLastPosition(position.getDeviceId()); + if (last != null) { + for (String attribute : attributesString.split("[ ,]")) { + if (last.getAttributes().containsKey(attribute) + && !position.getAttributes().containsKey(attribute)) { + position.getAttributes().put(attribute, last.getAttributes().get(attribute)); + } } } } diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java index 9d8ea044d..c2adfd799 100644 --- a/src/main/java/org/traccar/handler/DefaultDataHandler.java +++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ import org.traccar.BaseDataHandler; import org.traccar.database.DataManager; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class DefaultDataHandler extends BaseDataHandler { @@ -29,6 +31,7 @@ public class DefaultDataHandler extends BaseDataHandler { private final DataManager dataManager; + @Inject public DefaultDataHandler(DataManager dataManager) { this.dataManager = dataManager; } diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index 1e7e444f6..08c8c068d 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -1,6 +1,6 @@ /* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2015 Amila Silva - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.traccar.database.IdentityManager; import org.traccar.helper.DistanceCalculator; import org.traccar.model.Position; +import javax.inject.Inject; import java.math.BigDecimal; import java.math.RoundingMode; @@ -36,6 +37,7 @@ public class DistanceHandler extends BaseDataHandler { private final int coordinatesMinError; private final int coordinatesMaxError; + @Inject public DistanceHandler(Config config, IdentityManager identityManager) { this.identityManager = identityManager; this.filter = config.getBoolean(Keys.COORDINATES_FILTER); diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index 92da84e6b..be2a46ade 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,11 +21,14 @@ import org.traccar.BaseDataHandler; import org.traccar.database.IdentityManager; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class EngineHoursHandler extends BaseDataHandler { private final IdentityManager identityManager; + @Inject public EngineHoursHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index e576a26b8..0511ec98b 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,15 @@ import io.netty.channel.ChannelHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.DataManager; +import org.traccar.database.IdentityManager; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import javax.inject.Inject; import java.util.Date; @ChannelHandler.Sharable @@ -33,21 +35,27 @@ public class FilterHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(FilterHandler.class); - private boolean filterInvalid; - private boolean filterZero; - private boolean filterDuplicate; - private long filterFuture; - private boolean filterApproximate; - private int filterAccuracy; - private boolean filterStatic; - private int filterDistance; - private int filterMaxSpeed; - private long filterMinPeriod; - private boolean filterRelative; - private long skipLimit; - private boolean skipAttributes; - - public FilterHandler(Config config) { + private final boolean enabled; + private final boolean filterInvalid; + private final boolean filterZero; + private final boolean filterDuplicate; + private final long filterFuture; + private final boolean filterApproximate; + private final int filterAccuracy; + private final boolean filterStatic; + private final int filterDistance; + private final int filterMaxSpeed; + private final long filterMinPeriod; + private final boolean filterRelative; + private final long skipLimit; + private final boolean skipAttributes; + + private final IdentityManager identityManager; + private final DataManager dataManager; + + @Inject + public FilterHandler(Config config, IdentityManager identityManager, DataManager dataManager) { + enabled = config.getBoolean(Keys.FILTER_ENABLE); filterInvalid = config.getBoolean(Keys.FILTER_INVALID); filterZero = config.getBoolean(Keys.FILTER_ZERO); filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE); @@ -57,10 +65,12 @@ public class FilterHandler extends BaseDataHandler { filterStatic = config.getBoolean(Keys.FILTER_STATIC); filterDistance = config.getInteger(Keys.FILTER_DISTANCE); filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED); - filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000; + filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000L; filterRelative = config.getBoolean(Keys.FILTER_RELATIVE); skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000; skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE); + this.identityManager = identityManager; + this.dataManager = dataManager; } private boolean filterInvalid(Position position) { @@ -134,7 +144,7 @@ public class FilterHandler extends BaseDataHandler { private boolean skipAttributes(Position position) { if (skipAttributes) { - String attributesString = Context.getIdentityManager().lookupAttributeString( + String attributesString = identityManager.lookupAttributeString( position.getDeviceId(), "filter.skipAttributes", "", false, true); for (String attribute : attributesString.split("[ ,]")) { if (position.getAttributes().containsKey(attribute)) { @@ -173,7 +183,7 @@ public class FilterHandler extends BaseDataHandler { if (filterRelative) { try { Date newFixTime = position.getFixTime(); - preceding = Context.getDataManager().getPrecedingPosition(deviceId, newFixTime); + preceding = dataManager.getPrecedingPosition(deviceId, newFixTime); } catch (StorageException e) { LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); preceding = getLastReceivedPosition(deviceId); @@ -199,14 +209,8 @@ public class FilterHandler extends BaseDataHandler { } if (filterType.length() > 0) { - - StringBuilder message = new StringBuilder(); - message.append("Position filtered by "); - message.append(filterType.toString()); - message.append("filters from device: "); - message.append(Context.getIdentityManager().getById(deviceId).getUniqueId()); - - LOGGER.info(message.toString()); + String uniqueId = identityManager.getById(deviceId).getUniqueId(); + LOGGER.info("Position filtered by {}filters from device: {}", filterType, uniqueId); return true; } @@ -214,15 +218,12 @@ public class FilterHandler extends BaseDataHandler { } private Position getLastReceivedPosition(long deviceId) { - if (Context.getIdentityManager() != null) { - return Context.getIdentityManager().getLastPosition(deviceId); - } - return null; + return identityManager.getLastPosition(deviceId); } @Override protected Position handlePosition(Position position) { - if (filter(position)) { + if (enabled && filter(position)) { return null; } return position; diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java index aff3d8a64..2e3ed9d91 100644 --- a/src/main/java/org/traccar/handler/HemisphereHandler.java +++ b/src/main/java/org/traccar/handler/HemisphereHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,15 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class HemisphereHandler extends BaseDataHandler { private int latitudeFactor; private int longitudeFactor; + @Inject public HemisphereHandler(Config config) { String latitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE); if (latitudeHemisphere != null) { diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index e8051dd75..864eb455d 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,14 +19,18 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; import org.traccar.model.Position; +import org.traccar.reports.model.TripsConfig; + +import javax.inject.Inject; @ChannelHandler.Sharable public class MotionHandler extends BaseDataHandler { - private double speedThreshold; + private final double speedThreshold; - public MotionHandler(double speedThreshold) { - this.speedThreshold = speedThreshold; + @Inject + public MotionHandler(TripsConfig tripsConfig) { + speedThreshold = tripsConfig.getSpeedThreshold(); } @Override diff --git a/src/main/java/org/traccar/handler/RemoteAddressHandler.java b/src/main/java/org/traccar/handler/RemoteAddressHandler.java index c09b8c39a..809f67ca2 100644 --- a/src/main/java/org/traccar/handler/RemoteAddressHandler.java +++ b/src/main/java/org/traccar/handler/RemoteAddressHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,22 +18,34 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Position; +import javax.inject.Inject; import java.net.InetSocketAddress; @ChannelHandler.Sharable public class RemoteAddressHandler extends ChannelInboundHandlerAdapter { + private final boolean enabled; + + @Inject + public RemoteAddressHandler(Config config) { + enabled = config.getBoolean(Keys.PROCESSING_REMOTE_ADDRESS_ENABLE); + } + @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { - InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); - String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null; + if (enabled) { + InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); + String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null; - if (msg instanceof Position) { - Position position = (Position) msg; - position.set(Position.KEY_IP, hostAddress); + if (msg instanceof Position) { + Position position = (Position) msg; + position.set(Position.KEY_IP, hostAddress); + } } ctx.fireChannelRead(msg); diff --git a/src/main/java/org/traccar/handler/SpeedLimitHandler.java b/src/main/java/org/traccar/handler/SpeedLimitHandler.java index 65f2c9cfe..0469b9f16 100644 --- a/src/main/java/org/traccar/handler/SpeedLimitHandler.java +++ b/src/main/java/org/traccar/handler/SpeedLimitHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ import org.slf4j.LoggerFactory; import org.traccar.model.Position; import org.traccar.speedlimit.SpeedLimitProvider; +import javax.inject.Inject; + @ChannelHandler.Sharable public class SpeedLimitHandler extends ChannelInboundHandlerAdapter { @@ -30,6 +32,7 @@ public class SpeedLimitHandler extends ChannelInboundHandlerAdapter { private final SpeedLimitProvider speedLimitProvider; + @Inject public SpeedLimitHandler(SpeedLimitProvider speedLimitProvider) { this.speedLimitProvider = speedLimitProvider; } diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java index 822c22a0a..c7e5e6e5c 100644 --- a/src/main/java/org/traccar/handler/TimeHandler.java +++ b/src/main/java/org/traccar/handler/TimeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -31,11 +32,18 @@ import java.util.Set; @ChannelHandler.Sharable public class TimeHandler extends ChannelInboundHandlerAdapter { + private final boolean enabled; private final boolean useServerTime; private final Set protocols; + @Inject public TimeHandler(Config config) { - useServerTime = config.getString(Keys.TIME_OVERRIDE).equalsIgnoreCase("serverTime"); + enabled = config.hasKey(Keys.TIME_OVERRIDE); + if (enabled) { + useServerTime = config.getString(Keys.TIME_OVERRIDE).equalsIgnoreCase("serverTime"); + } else { + useServerTime = false; + } String protocolList = Context.getConfig().getString(Keys.TIME_PROTOCOLS); if (protocolList != null) { protocols = new HashSet<>(Arrays.asList(protocolList.split("[, ]"))); @@ -47,7 +55,7 @@ public class TimeHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { - if (msg instanceof Position && (protocols == null + if (enabled && msg instanceof Position && (protocols == null || protocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName()))) { Position position = (Position) msg; diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java index 05dbc516e..6e7b0b16e 100644 --- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,12 +25,15 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class AlertEventHandler extends BaseEventHandler { private final IdentityManager identityManager; private final boolean ignoreDuplicateAlerts; + @Inject public AlertEventHandler(Config config, IdentityManager identityManager) { this.identityManager = identityManager; ignoreDuplicateAlerts = config.getBoolean(Keys.EVENT_IGNORE_DUPLICATE_ALERTS); diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java index 767cef3f6..bbf749cdc 100644 --- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.Collections; import java.util.Map; @@ -34,6 +35,7 @@ public class BehaviorEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public BehaviorEventHandler(Config config, IdentityManager identityManager) { accelerationThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_ACCELERATION_THRESHOLD); brakingThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_BRAKING_THRESHOLD); diff --git a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java index 9b7ff554e..858f84e09 100644 --- a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java +++ b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,15 @@ import io.netty.channel.ChannelHandler; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class CommandResultEventHandler extends BaseEventHandler { + @Inject + public CommandResultEventHandler() { + } + @Override protected Map analyzePosition(Position position) { Object commandResult = position.getAttributes().get(Position.KEY_RESULT); diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java index 6fdf4246b..510ac3465 100644 --- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,11 +24,14 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class DriverEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public DriverEventHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java index 343a17311..7849abff9 100644 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.Collections; import java.util.Map; @@ -31,6 +32,7 @@ public class FuelDropEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public FuelDropEventHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index dae0c891f..36df7aaf3 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,8 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { @@ -38,6 +40,7 @@ public class GeofenceEventHandler extends BaseEventHandler { private final CalendarManager calendarManager; private final ConnectionManager connectionManager; + @Inject public GeofenceEventHandler( IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, ConnectionManager connectionManager) { diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 69df9a46b..9887c9db6 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,11 +25,14 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class IgnitionEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public IgnitionEventHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 0f960ad1f..5b9ce4316 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,12 +26,15 @@ import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class MaintenanceEventHandler extends BaseEventHandler { private final IdentityManager identityManager; private final MaintenancesManager maintenancesManager; + @Inject public MaintenanceEventHandler(IdentityManager identityManager, MaintenancesManager maintenancesManager) { this.identityManager = identityManager; this.maintenancesManager = maintenancesManager; diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index db276f32b..23a39d070 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +29,8 @@ import org.traccar.model.Position; import org.traccar.reports.ReportUtils; import org.traccar.reports.model.TripsConfig; +import javax.inject.Inject; + @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { @@ -36,6 +38,7 @@ public class MotionEventHandler extends BaseEventHandler { private final DeviceManager deviceManager; private final TripsConfig tripsConfig; + @Inject public MotionEventHandler(IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { this.identityManager = identityManager; this.deviceManager = deviceManager; diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 347ad9005..102003c3c 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,6 +30,8 @@ import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class OverspeedEventHandler extends BaseEventHandler { @@ -43,6 +45,7 @@ public class OverspeedEventHandler extends BaseEventHandler { private final long minimalDuration; private final boolean preferLowest; + @Inject public OverspeedEventHandler(Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { this.deviceManager = deviceManager; this.geofenceManager = geofenceManager; diff --git a/src/main/java/org/traccar/reports/model/TripsConfig.java b/src/main/java/org/traccar/reports/model/TripsConfig.java index 0f0c615d3..34c445f8b 100644 --- a/src/main/java/org/traccar/reports/model/TripsConfig.java +++ b/src/main/java/org/traccar/reports/model/TripsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +18,6 @@ package org.traccar.reports.model; public class TripsConfig { - public TripsConfig() { - } - public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { this.minimalTripDistance = minimalTripDistance; @@ -32,74 +29,46 @@ public class TripsConfig { this.speedThreshold = speedThreshold; } - private double minimalTripDistance; + private final double minimalTripDistance; public double getMinimalTripDistance() { return minimalTripDistance; } - public void setMinimalTripDistance(double minimalTripDistance) { - this.minimalTripDistance = minimalTripDistance; - } - - private long minimalTripDuration; + private final long minimalTripDuration; public long getMinimalTripDuration() { return minimalTripDuration; } - public void setMinimalTripDuration(long minimalTripDuration) { - this.minimalTripDuration = minimalTripDuration; - } - - private long minimalParkingDuration; + private final long minimalParkingDuration; public long getMinimalParkingDuration() { return minimalParkingDuration; } - public void setMinimalParkingDuration(long minimalParkingDuration) { - this.minimalParkingDuration = minimalParkingDuration; - } - - private long minimalNoDataDuration; + private final long minimalNoDataDuration; public long getMinimalNoDataDuration() { return minimalNoDataDuration; } - public void setMinimalNoDataDuration(long minimalNoDataDuration) { - this.minimalNoDataDuration = minimalNoDataDuration; - } - - private boolean useIgnition; + private final boolean useIgnition; public boolean getUseIgnition() { return useIgnition; } - public void setUseIgnition(boolean useIgnition) { - this.useIgnition = useIgnition; - } - - private boolean processInvalidPositions; + private final boolean processInvalidPositions; public boolean getProcessInvalidPositions() { return processInvalidPositions; } - public void setProcessInvalidPositions(boolean processInvalidPositions) { - this.processInvalidPositions = processInvalidPositions; - } - - private double speedThreshold; + private final double speedThreshold; public double getSpeedThreshold() { return speedThreshold; } - public void setSpeedThreshold(double speedThreshold) { - this.speedThreshold = speedThreshold; - } - } diff --git a/src/test/java/org/traccar/TestIdentityManager.java b/src/test/java/org/traccar/TestIdentityManager.java index 7d2865e74..68d98db9a 100644 --- a/src/test/java/org/traccar/TestIdentityManager.java +++ b/src/test/java/org/traccar/TestIdentityManager.java @@ -53,9 +53,6 @@ public final class TestIdentityManager implements IdentityManager { @Override public String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { - if (attributeName.equals("filter.skipAttributes")) { - return "alarm,result"; - } return defaultValue; } diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java index ad8d244a6..49bbf70b5 100644 --- a/src/test/java/org/traccar/handler/FilterHandlerTest.java +++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java @@ -5,70 +5,77 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.DataManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; import org.traccar.model.Position; - import java.util.Date; - import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.*; public class FilterHandlerTest extends BaseTest { - private FilterHandler passingHandler = new FilterHandler(new Config()); + private FilterHandler passingHandler; private FilterHandler filteringHandler; @Before - public void before() { - Config config = new Config(); - config.setString(Keys.FILTER_INVALID, String.valueOf(true)); - config.setString(Keys.FILTER_ZERO, String.valueOf(true)); - config.setString(Keys.FILTER_DUPLICATE, String.valueOf(true)); - config.setString(Keys.FILTER_FUTURE, String.valueOf(5 * 60)); - config.setString(Keys.FILTER_APPROXIMATE, String.valueOf(true)); - config.setString(Keys.FILTER_STATIC, String.valueOf(true)); - config.setString(Keys.FILTER_DISTANCE, String.valueOf(10)); - config.setString(Keys.FILTER_MAX_SPEED, String.valueOf(500)); - config.setString(Keys.FILTER_SKIP_LIMIT, String.valueOf(10)); - config.setString(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE, String.valueOf(true)); - filteringHandler = new FilterHandler(config); + public void passingHandler() { + var config = mock(Config.class); + when(config.getBoolean(Keys.FILTER_ENABLE)).thenReturn(true); + var identityManager = mock(IdentityManager.class); + var dataManager = mock(DataManager.class); + passingHandler = new FilterHandler(config, identityManager, dataManager); } - private Position createPosition( - long deviceId, - Date time, - boolean valid, - double latitude, - double longitude, - double altitude, - double speed, - double course) { + @Before + public void filteringHandler() { + var config = mock(Config.class); + when(config.getBoolean(Keys.FILTER_ENABLE)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_INVALID)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_ZERO)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_DUPLICATE)).thenReturn(true); + when(config.getLong(Keys.FILTER_FUTURE)).thenReturn(5 * 60L); + when(config.getBoolean(Keys.FILTER_APPROXIMATE)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_STATIC)).thenReturn(true); + when(config.getInteger(Keys.FILTER_DISTANCE)).thenReturn(10); + when(config.getInteger(Keys.FILTER_MAX_SPEED)).thenReturn(500); + when(config.getLong(Keys.FILTER_SKIP_LIMIT)).thenReturn(10L); + when(config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE)).thenReturn(true); + var identityManager = mock(IdentityManager.class); + when(identityManager.lookupAttributeString(0, "filter.skipAttributes", "", false, true)).thenReturn("alarm,result"); + when(identityManager.getById(0)).thenReturn(mock(Device.class)); + var dataManager = mock(DataManager.class); + filteringHandler = new FilterHandler(config, identityManager, dataManager); + } + private Position createPosition(Date time, boolean valid, double speed) { Position position = new Position(); - position.setDeviceId(deviceId); + position.setDeviceId(0); position.setTime(time); position.setValid(valid); - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAltitude(altitude); + position.setLatitude(10); + position.setLongitude(10); + position.setAltitude(10); position.setSpeed(speed); - position.setCourse(course); + position.setCourse(10); return position; } @Test public void testFilter() { - Position position = createPosition(0, new Date(), true, 10, 10, 10, 10, 10); + Position position = createPosition(new Date(), true, 10); assertNotNull(filteringHandler.handlePosition(position)); assertNotNull(passingHandler.handlePosition(position)); - position = createPosition(0, new Date(Long.MAX_VALUE), true, 10, 10, 10, 10, 10); + position = createPosition(new Date(Long.MAX_VALUE), true, 10); assertNull(filteringHandler.handlePosition(position)); assertNotNull(passingHandler.handlePosition(position)); - position = createPosition(0, new Date(), false, 10, 10, 10, 10, 10); + position = createPosition(new Date(), false, 10); assertNull(filteringHandler.handlePosition(position)); assertNotNull(passingHandler.handlePosition(position)); @@ -78,7 +85,7 @@ public class FilterHandlerTest extends BaseTest { @Test public void testSkipAttributes() { - Position position = createPosition(0, new Date(), true, 10, 10, 10, 0, 10); + Position position = createPosition(new Date(), true, 0); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); assertNotNull(filteringHandler.handlePosition(position)); diff --git a/src/test/java/org/traccar/handler/MotionHandlerTest.java b/src/test/java/org/traccar/handler/MotionHandlerTest.java index 9e0859664..fdbd48334 100644 --- a/src/test/java/org/traccar/handler/MotionHandlerTest.java +++ b/src/test/java/org/traccar/handler/MotionHandlerTest.java @@ -1,16 +1,21 @@ package org.traccar.handler; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; import org.junit.Test; import org.traccar.model.Position; +import org.traccar.reports.model.TripsConfig; public class MotionHandlerTest { @Test public void testCalculateMotion() { - MotionHandler motionHandler = new MotionHandler(0.01); + TripsConfig tripsConfig = mock(TripsConfig.class); + when(tripsConfig.getSpeedThreshold()).thenReturn(0.01); + + MotionHandler motionHandler = new MotionHandler(tripsConfig); Position position = motionHandler.handlePosition(new Position()); -- cgit v1.2.3 From 12e36b50fe063bd7ec93464b035d78376f7e9046 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 09:18:53 -0700 Subject: Remove script in favor of action --- setup/environment.sh | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 setup/environment.sh (limited to 'setup') diff --git a/setup/environment.sh b/setup/environment.sh deleted file mode 100644 index 86a50cc85..000000000 --- a/setup/environment.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -add-apt-repository ppa:openjdk-r/ppa -curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - -dpkg --add-architecture i386 -apt update -apt install -y git openjdk-11-jdk zip unzip innoextract wine wine32 makeself nodejs - -# /usr/bin/printf '\xfe\xed\xfe\xed\x00\x00\x00\x02\x00\x00\x00\x00\xe2\x68\x6e\x45\xfb\x43\xdf\xa4\xd9\x92\xdd\x41\xce\xb6\xb2\x1c\x63\x30\xd7\x92' > /etc/ssl/certs/java/cacerts -# /var/lib/dpkg/info/ca-certificates-java.postinst configure - -git clone --recurse-submodules https://github.com/traccar/traccar.git -(cd traccar/traccar-web && git checkout master) -(cd traccar && ./gradlew build) - -wget http://cdn.sencha.com/cmd/7.1.0.15/no-jre/SenchaCmd-7.1.0.15-linux-i386.sh.zip -unzip SenchaCmd-*.zip ; rm SenchaCmd-*.zip -./SenchaCmd-*.sh -q ; rm SenchaCmd-* -export PATH=$PATH:~/bin/Sencha/Cmd/ - -(cd traccar/traccar-web && ./tools/package.sh) - -cd traccar/setup -wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe -wget https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip -wget https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip -wget https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip -- cgit v1.2.3 From b9d78159d736391ca2602d77fc8dbea358e89e59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 15:22:55 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 8ce916432..8ba907843 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.0", + "Implementation-Version": "5.1", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 64137f8d6..32d1846f5 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.0 +AppVersion=5.1 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 77100dd32..ecdc4a407 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.0", + "version": "5.1", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From e475512473459b596e432dc2743784b6d58243ea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 09:35:19 -0700 Subject: Update version numbers --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 675d1490f..36fc2f6df 100644 --- a/build.gradle +++ b/build.gradle @@ -98,7 +98,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.1", + "Implementation-Version": "5.2", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 32d1846f5..7734f3956 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.1 +AppVersion=5.2 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index ecdc4a407..77ca20ce2 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.1", + "version": "5.2", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From fd221e21f21e04132742e34056db696b6156e5a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:10:53 -0700 Subject: Disable sanitization by default --- debug.xml | 1 - setup/default.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'setup') diff --git a/debug.xml b/debug.xml index b38b4f9ac..e02c1b15d 100644 --- a/debug.xml +++ b/debug.xml @@ -7,7 +7,6 @@ ./setup/default.xml ./traccar-web/web - false true true diff --git a/setup/default.xml b/setup/default.xml index dea638d7a..62494f814 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -12,7 +12,7 @@ 8082 ./web - true + false false true -- cgit v1.2.3 From 346441e52256bca70b88dc6adad6bd3aa97da2a1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:16:27 -0700 Subject: Split web paths --- setup/default.xml | 2 +- setup/package.sh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 62494f814..0abc96431 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -11,7 +11,7 @@ --> 8082 - ./web + ./modern false false diff --git a/setup/package.sh b/setup/package.sh index e5f976b79..40dac475d 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -81,13 +81,14 @@ else fi prepare () { - mkdir -p out/{conf,data,lib,logs,web,schema,templates} + mkdir -p out/{conf,data,lib,logs,legacy,modern,schema,templates} cp ../target/tracker-server.jar out cp ../target/lib/* out/lib cp ../schema/* out/schema cp -r ../templates/* out/templates - cp -r ../traccar-web/web/* out/web + cp -r ../traccar-web/web/* out/legacy + cp -r ../traccar-web/modern/build/* out/modern cp default.xml out/conf cp traccar.xml out/conf -- cgit v1.2.3 From 315be9dd7425c36cb612af1155f3195baf06bc6f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 21:00:54 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 135654c9d..1b1fbb738 100644 --- a/build.gradle +++ b/build.gradle @@ -98,7 +98,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.2", + "Implementation-Version": "5.3", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 7734f3956..3e946e672 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.2 +AppVersion=5.3 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 77ca20ce2..866ac8a7d 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.2", + "version": "5.3", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", @@ -27,6 +27,10 @@ "url": "https://demo3.traccar.org/api", "description": "Demo Server 3" }, + { + "url": "https://demo4.traccar.org/api", + "description": "Demo Server 4" + }, { "url": "https://server.traccar.org/api", "description": "Subscription Server" -- cgit v1.2.3 From 8fb2596c60d8e63e9933de4b077253f14daa1472 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 17:47:25 -0700 Subject: Implement BSTPL protocol --- setup/default.xml | 1 + .../java/org/traccar/protocol/BstplProtocol.java | 43 +++++++ .../org/traccar/protocol/BstplProtocolDecoder.java | 137 +++++++++++++++++++++ .../traccar/protocol/BstplProtocolDecoderTest.java | 21 ++++ 4 files changed, 202 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/BstplProtocol.java create mode 100644 src/main/java/org/traccar/protocol/BstplProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 0abc96431..607efc35f 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -283,5 +283,6 @@ 5238 5239 5240 + 5241 diff --git a/src/main/java/org/traccar/protocol/BstplProtocol.java b/src/main/java/org/traccar/protocol/BstplProtocol.java new file mode 100644 index 000000000..dde14a2ca --- /dev/null +++ b/src/main/java/org/traccar/protocol/BstplProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class BstplProtocol extends BaseProtocol { + + @Inject + public BstplProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new BstplProtocolDecoder(BstplProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java new file mode 100644 index 000000000..15c114642 --- /dev/null +++ b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java @@ -0,0 +1,137 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class BstplProtocolDecoder extends BaseProtocolDecoder { + + public BstplProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("BSTPL$") // header + .number("(d),") // type + .expression("([^,]+),") // device id + .expression("([AV]),") // validity + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d+.d+),([0NS]),") // latitude + .number("(d+.d+),([0EW]),") // longitude + .number("(d+),") // speed + .number("(d+),") // odometer + .number("(d+),") // course + .number("(d+),") // satellites + .number("([01]),") // box open + .number("(d+),") // rssi + .number("([01]),") // charge + .number("([01]),") // ignition + .number("([01]),") // engine + .number("([01]),") // locked + .number("(d+.d+),") // adc + .number("d+,") // reserved + .number("(d+.d+),") // battery + .expression("([^,]+),") // firmware + .number("([^,]+),") // iccid + .number("(d+.d+)") // power + .compile(); + + private String decodeAlarm(int value) { + switch (value) { + case 4: + return Position.ALARM_LOW_BATTERY; + case 5: + return Position.ALARM_ACCELERATION; + case 6: + return Position.ALARM_BRAKING; + case 7: + return Position.ALARM_OVERSPEED; + case 9: + return Position.ALARM_SOS; + default: + return null; + } + } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + int type = parser.nextInt(); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_ALARM, decodeAlarm(type)); + + position.setValid(parser.next().equals("A")); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + + position.set(Position.KEY_ODOMETER, parser.nextInt() * 1000L); + + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + boolean boxOpen = parser.nextInt() > 0; + if (type == 8 && boxOpen) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + position.set("boxOpen", boxOpen); + + position.set(Position.KEY_RSSI, parser.nextInt()); + + boolean charge = parser.nextInt() > 0; + if (type == 3) { + position.set(Position.KEY_ALARM, charge ? Position.ALARM_POWER_RESTORED : Position.ALARM_POWER_CUT); + } + position.set(Position.KEY_CHARGE, charge); + + position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + position.set("engine", parser.nextInt() > 0); + position.set(Position.KEY_BLOCKED, parser.nextInt() > 0); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + position.set(Position.KEY_ICCID, parser.next()); + position.set(Position.KEY_POWER, parser.nextDouble()); + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java new file mode 100644 index 000000000..ae4c47229 --- /dev/null +++ b/src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class BstplProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new BstplProtocolDecoder(null)); + + verifyPosition(decoder, text( + "BSTPL$1,869630054439504,V,200722,045113,00.000000,0,00.00000,0,0,0,000,00,0,17,1,1,0,0,00.01,0,04.19,15B_190821,8991000907387031196F,12.27")); + + verifyPosition(decoder, text( + "BSTPL$1,AP12AP3456,A,130720,160552,27.244183,N,83.673973,E,20,156,183,17,0,11,1,0,0,0,00.00,00,04.16,15_V1_0_0,89917380578146790443,12.16")); + + } + +} -- cgit v1.2.3 From 596315224144c78bff043a3e3a67b005ec0a0e30 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 Aug 2022 16:42:11 -0700 Subject: Update package script --- setup/package.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'setup') diff --git a/setup/package.sh b/setup/package.sh index 40dac475d..3cfe88a52 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -61,17 +61,17 @@ fi if [ $PLATFORM = "all" -o $PLATFORM = "windows-64" ]; then check_requirement "Inno Extractor" "which innoextract" "Missing innoextract binary" check_requirement "Inno Setup" "ls i*setup-*.exe" "Missing Inno Setup (http://www.jrsoftware.org/isdl.php)" - check_requirement "Windows 64 Java" "ls java-*.windows.ojdkbuild.x86_64.zip" "Missing Windows 64 Java (https://github.com/ojdkbuild/ojdkbuild)" + check_requirement "Windows 64 Java" "ls OpenJDK*x64_windows*.zip" "Missing Windows 64 JDK (https://adoptium.net/)" check_requirement "Wine" "which wine" "Missing wine binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" -o $PLATFORM = "linux-arm" ]; then check_requirement "Makeself" "which makeself" "Missing makeself binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" ]; then - check_requirement "Linux 64 Java" "ls jdk-*-linux-x64.zip" "Missing Linux 64 Java (https://github.com/ojdkbuild/contrib_jdk11u-ci/releases)" + check_requirement "Linux 64 Java" "ls OpenJDK*x64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm" ]; then - check_requirement "Linux ARM Java" "ls jdk-*-linux-armhf.zip" "Missing Linux ARM Java (https://github.com/ojdkbuild/contrib_jdk11u-aarch32-ci/releases)" + check_requirement "Linux ARM Java" "ls OpenJDK*arm_linux*.tar.gz" "Missing Linux ARM JDK (https://adoptium.net/)" fi if [ $PREREQ = false ]; then info "Missing build requirements, aborting..." @@ -119,9 +119,9 @@ package_other () { package_windows () { info "Building Windows 64 installer" - unzip -q -o java-*.windows.ojdkbuild.x86_64.zip - jlink --module-path java-*.windows.ojdkbuild.x86_64/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre - rm -rf java-*.windows.ojdkbuild.x86_64 + unzip -q OpenJDK*x64_windows*.zip + jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre + rm -rf jdk-* wine app/ISCC.exe traccar.iss >/dev/null rm -rf out/jre zip -q -j traccar-windows-64-$VERSION.zip Output/traccar-setup.exe README.txt @@ -133,13 +133,13 @@ package_linux () { cp setup.sh out cp traccar.service out - unzip -q -o jdk-*-linux-$1.zip - jlink --module-path jdk-*-linux-$1/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre - rm -rf jdk-*-linux-$1 + tar -xf OpenJDK*$1_linux*.tar.gz + jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre + rm -rf jdk-* makeself --needroot --quiet --notemp out traccar.run "traccar" ./setup.sh rm -rf out/jre - zip -q -j traccar-linux-$2-$VERSION.zip traccar.run README.txt + zip -q -j traccar-linux-$1-$VERSION.zip traccar.run README.txt rm traccar.run rm out/setup.sh @@ -148,13 +148,13 @@ package_linux () { package_linux_64 () { info "Building Linux 64 installer" - package_linux x64 64 + package_linux x64 ok "Created Linux 64 installer" } package_linux_arm () { info "Building Linux ARM installer" - package_linux armhf arm + package_linux arm ok "Created Linux ARM installer" } -- cgit v1.2.3 From 4f60122750cc61b5f2112a285036a98957b8273b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 Aug 2022 17:16:11 -0700 Subject: Fix linux package name --- setup/package.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'setup') diff --git a/setup/package.sh b/setup/package.sh index 3cfe88a52..71b86014f 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -61,14 +61,14 @@ fi if [ $PLATFORM = "all" -o $PLATFORM = "windows-64" ]; then check_requirement "Inno Extractor" "which innoextract" "Missing innoextract binary" check_requirement "Inno Setup" "ls i*setup-*.exe" "Missing Inno Setup (http://www.jrsoftware.org/isdl.php)" - check_requirement "Windows 64 Java" "ls OpenJDK*x64_windows*.zip" "Missing Windows 64 JDK (https://adoptium.net/)" + check_requirement "Windows 64 Java" "ls OpenJDK*64_windows*.zip" "Missing Windows 64 JDK (https://adoptium.net/)" check_requirement "Wine" "which wine" "Missing wine binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" -o $PLATFORM = "linux-arm" ]; then check_requirement "Makeself" "which makeself" "Missing makeself binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" ]; then - check_requirement "Linux 64 Java" "ls OpenJDK*x64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" + check_requirement "Linux 64 Java" "ls OpenJDK*64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm" ]; then check_requirement "Linux ARM Java" "ls OpenJDK*arm_linux*.tar.gz" "Missing Linux ARM JDK (https://adoptium.net/)" @@ -119,7 +119,7 @@ package_other () { package_windows () { info "Building Windows 64 installer" - unzip -q OpenJDK*x64_windows*.zip + unzip -q OpenJDK*64_windows*.zip jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre rm -rf jdk-* wine app/ISCC.exe traccar.iss >/dev/null @@ -148,7 +148,7 @@ package_linux () { package_linux_64 () { info "Building Linux 64 installer" - package_linux x64 + package_linux 64 ok "Created Linux 64 installer" } -- cgit v1.2.3 From 3574169d57b9619ec4dfb90694c9c9ae37c1896f Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 13:10:22 +0100 Subject: Added G1RUS port to default.xml --- setup/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 607efc35f..f5e28e18b 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -284,5 +284,5 @@ 5239 5240 5241 - + 5242 -- cgit v1.2.3 From d4513fa86539577e24ede46d40748d8d034b025c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 10:47:37 +0100 Subject: Added support for NDTPv6 protocol --- setup/default.xml | 1 + .../org/traccar/protocol/NDTPv6FrameDecoder.java | 32 +++ .../java/org/traccar/protocol/NDTPv6Protocol.java | 26 ++ .../traccar/protocol/NDTPv6ProtocolDecoder.java | 309 +++++++++++++++++++++ .../traccar/protocol/NDTPv6ProtocolEncoder.java | 38 +++ 5 files changed, 406 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java create mode 100644 src/main/java/org/traccar/protocol/NDTPv6Protocol.java create mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java create mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 607efc35f..4f1e3ca30 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -284,5 +284,6 @@ 5239 5240 5241 + 5242 diff --git a/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java b/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java new file mode 100644 index 000000000..c869b11a4 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class NDTPv6FrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + return buf; + } + +} diff --git a/src/main/java/org/traccar/protocol/NDTPv6Protocol.java b/src/main/java/org/traccar/protocol/NDTPv6Protocol.java new file mode 100644 index 000000000..78dc11b50 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6Protocol.java @@ -0,0 +1,26 @@ +/* + * 2020 - NDTP v6 Protocol + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class NDTPv6Protocol extends BaseProtocol { + + @Inject + public NDTPv6Protocol(Config config) { + addServer( + new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new NDTPv6ProtocolDecoder(NDTPv6Protocol.this)); + } + } + ); + } +} diff --git a/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java new file mode 100644 index 000000000..788afd65b --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java @@ -0,0 +1,309 @@ +/* + * 2020 - NDTP v6 Protocol Decoder + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; + +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Date; + +import org.traccar.BaseProtocolDecoder; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +public class NDTPv6ProtocolDecoder extends BaseProtocolDecoder { + + public NDTPv6ProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final byte[] SIGNATURE = {0x7E, 0x7E}; + + private static final int NPL_FLAG_CRC = 2; + private static final int NPH_RESULT_OK = 0x00000000; + private static final int NPL_TYPE_NPH = 2; + private static final int NPL_ADDRESS_SERVER = 0; + + /* common packets for all services */ + private static final int NPH_RESULT = 0; + + /* NPH service types */ + private static final int NPH_SRV_GENERIC_CONTROLS = 0; + private static final int NPH_SRV_NAVDATA = 1; + + /* NPH_SRV_GENERIC_CONTROLS packets */ + private static final int NPH_SGC_RESULT = NPH_RESULT; + private static final int NPH_SGC_CONN_REQUEST = 100; + + /* NPH_SRV_NAVDATA packets */ + private static final int NPH_SND_RESULT = NPH_RESULT; + + private static void sendResultResponse( + Channel channel, + short serviceId, + int requestId, + int nphSendResult, + int nphResult + ) { + // Формирование пакета данных + byte[] serviceIdBytes = ByteBuffer + .allocate(2) + .order(ByteOrder.LITTLE_ENDIAN) + .putShort(serviceId) + .array(); + byte[] nphSendResultBytes = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt(nphSendResult) + .array(); + byte[] requestIdBytes = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt(requestId) + .array(); + byte[] nphResultBytes = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt(nphResult) + .array(); + + byte[] allByteArray = new byte[serviceIdBytes.length + + requestIdBytes.length + + nphSendResultBytes.length + + nphResultBytes.length]; + + System.arraycopy(serviceIdBytes, 0, allByteArray, 0, serviceIdBytes.length); + System.arraycopy( + nphSendResultBytes, + 0, + allByteArray, + serviceIdBytes.length, + nphSendResultBytes.length + ); + System.arraycopy( + requestIdBytes, + 0, + allByteArray, + serviceIdBytes.length + nphSendResultBytes.length, + requestIdBytes.length + ); + System.arraycopy( + nphResultBytes, + 0, + allByteArray, + serviceIdBytes.length + requestIdBytes.length + nphSendResultBytes.length, + nphResultBytes.length + ); + + // ПАКЕТ ОТВЕТА КЛИЕНТУ + ByteBuf response = Unpooled.buffer(); + // NPL + response.writeBytes(SIGNATURE); + response.writeShortLE(allByteArray.length); // Размер данных + response.writeShortLE(NPL_FLAG_CRC); // Флаги + + response.writeShort( + Checksum.crc16(Checksum.CRC16_MODBUS, ByteBuffer.wrap(allByteArray)) + ); // CRC + response.writeByte(NPL_TYPE_NPH); // Тип + response.writeIntLE(NPL_ADDRESS_SERVER); // peer_address + response.writeShortLE(0); // request_id + + response.writeBytes(allByteArray); + + channel.writeAndFlush( + new NetworkMessage(response, channel.remoteAddress()) + ); + } + + private static final short MAIN_NAV_DATA = 0; + private static final short ADDITIONAL_NAV_DATA = 2; + + private void decodeData(ByteBuf buf, Position position, int dataType) { + if (dataType == NPH_SRV_NAVDATA) { + short cellType; + short cellNumber; + + cellType = buf.readUnsignedByte(); // Тип ячейки + cellNumber = buf.readUnsignedByte(); // Номер ячейки + if (cellType == MAIN_NAV_DATA && (cellNumber == 0 || cellNumber == 1)) { + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); // Значение реального времени unix + position.setLongitude(buf.readIntLE() / 10000000.0); // Долгота в градусах, умноженная на 10 000 000 + position.setLatitude(buf.readIntLE() / 10000000.0); // Широта в градусах, умноженная на 10 000 000 + + short flags = buf.readUnsignedByte(); // Достоверность навигационных данных: + // bit7 - достоверность нав. данных (1 - достоверны, 0 – нет); + // bit6 - полушарие долготы (1 – E, 0 – W); + // bit5 - полушарие широты (1 – N, 0 – S); + // bit4 - флаг работы от встроенного аккумулятора; + // bit3 – флаг первоначального включения; + // bit2 – состояние SOS (1 – SOS, 0 – нет SOS); + // bit1 – флаг тревожной информации (один из параметров + // находится в диапазоне тревоги) + position.setValid(BitUtil.check(flags, 7)); + if (BitUtil.check(flags, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 20); // Напряжение батареи, 1бит = 20мВ + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); // Средняя скорость за период в км/ч + position.setSpeed(buf.readUnsignedShortLE() / 1.85); // Максимальная скорость за период в км/ч + + int course = buf.readUnsignedShortLE(); // Направление движения + position.setCourse(course); + + position.set(Position.KEY_DISTANCE, buf.readUnsignedShortLE()); // Пройденный путь, м + position.setAltitude(buf.readShortLE()); // Высота над уровнем моря в метрах (-18000 - +18000) + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); // Количество видимых спутников + position.set(Position.KEY_PDOP, buf.readUnsignedByte()); // PDOP + } + cellType = buf.readUnsignedByte(); // Тип ячейки + cellNumber = buf.readUnsignedByte(); // Номер ячейки + if (cellType == ADDITIONAL_NAV_DATA && cellNumber == 0) { + int analogIn1 = buf.readUnsignedShortLE(); // Значение 0 аналогового входа в 16 битном формате + //(analogIn1 - отражает напряжение на батерии для радиоборта) + int analogIn2 = buf.readUnsignedShortLE(); // Значение 1 аналогового входа в 16 битном формате + int analogIn3 = buf.readUnsignedShortLE(); // Значение 2 аналогового входа в 16 битном формате + int analogIn4 = buf.readUnsignedShortLE(); // Значение 3 аналогового входа в 16 битном формате + + buf.readUnsignedByte(); // Значение цифровых входов + buf.readUnsignedByte(); // Состояние дискретных выходов + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 0 с предыдущей нав. отметки + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 1 с предыдущей нав. отметки + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 2 с предыдущей нав. отметки + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 3 с предыдущей нав. отметки + buf.readUnsignedIntLE(); // Длина трека с момента первого включения + + position.set(Position.KEY_ANTENNA, buf.readUnsignedByte()); // Сила GSM сигнала + position.set(Position.KEY_GPS, buf.readUnsignedByte()); // Состояние GPRS подключения + position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); // Акселерометр - энергия + position.set(Position.KEY_POWER, buf.readUnsignedByte() * 200); // Напряжение борт. сети (1бит - 200мв) + + position.set(Position.PREFIX_ADC + 1, analogIn1 * 1); + position.set(Position.PREFIX_ADC + 2, analogIn2 * 1); + position.set(Position.PREFIX_ADC + 3, analogIn3 * 1); + position.set(Position.PREFIX_ADC + 4, analogIn4 * 1); + + // Расчет уровня батареи + // float Voltage = 5 / 4096 * analogIn1; // Вольтаж + + float batteryLevel = (analogIn1 - 3600) / 6; + + if (batteryLevel > 100) { + batteryLevel = 100; + } + if (batteryLevel < 0) { + batteryLevel = 0; + } + + position.set(Position.KEY_BATTERY_LEVEL, batteryLevel); + } + } + } + + @Override + protected Object decode( + Channel channel, + SocketAddress remoteAddress, + Object msg + ) + throws Exception { + ByteBuf buf = (ByteBuf) msg; + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + + // Заголовок NPL + buf.skipBytes(2); // Сигнатура (7e 7e) + buf.readUnsignedShortLE(); // Размер данных (nph + размер массива данных) + buf.readUnsignedShortLE(); // Флаги соединения (2 - проверять crc) + buf.readUnsignedShortLE(); // CRC (Modbus) + buf.readUnsignedByte(); // Тип пакета (nph) + buf.readUnsignedIntLE(); // Адрес участника соединения + buf.readUnsignedShortLE(); // Идентификатор NPL + + // Заголовок NPH + int serviceId = buf.readUnsignedShortLE(); // Идентификатор услуги (NPH_SRV_NAVDATA) service_id + int serviceType = buf.readUnsignedShortLE(); // Тип пакета + buf.readUnsignedShortLE(); // Флаг (1 - требуется подтверждение) NPH_FLAG_REQUEST + long requestId = buf.readUnsignedIntLE(); // Идентификатор nph + + if ( + deviceSession == null && + serviceId == NPH_SRV_GENERIC_CONTROLS && + serviceType == NPH_SGC_CONN_REQUEST + ) { // Регистрация устройства + buf.readUnsignedShortLE(); // Версия протокола NDTP (старший номер) + buf.readUnsignedShortLE(); // Версия протокола NDTP (младший номер) + buf.readUnsignedShortLE(); // Опции соединения (connection_flags) + // Определяет настройки соединения, + // которые будут использоваться после установки соединения. + // На данный момент их две: + // - бит0: шифровать пакеты (0 - нет, 1 — да) + // - бит1: рассчитывать CRC пакетов (0 - нет, 1 — да) + // - бит2: подключение симулятора (0 — подключается обычный клиент, + // 1 подключается симулятор) + // - бит3: тип алгоритма шифрования. + // - 0 - blowfish + // - 1 – ГОСТ + // - бит8: наличие поля IMEI (0 - нет, 1 — да) + // - бит9: наличие поля IMSI (0 - нет, 1 — да) + // - остальные биты не используются. + int deviceId = buf.readUnsignedShortLE(); + Position position = new Position(getProtocolName()); + deviceSession = + getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResultResponse( + channel, + (short) serviceId, + (int) requestId, + NPH_SND_RESULT, + NPH_RESULT_OK + ); + } + + position.set(Position.KEY_RESULT, String.valueOf(NPH_SGC_RESULT)); + position.setTime(new Date()); + getLastLocation(position, new Date()); + position.setValid(false); + + return position; + } + + if (serviceId == NPH_SRV_NAVDATA) { + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResultResponse( + channel, + (short) serviceId, + (int) requestId, + NPH_SND_RESULT, + NPH_RESULT_OK + ); + } + + decodeData(buf, position, NPH_SRV_NAVDATA); + + return position; + } + + return null; + } +} diff --git a/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java b/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java new file mode 100644 index 000000000..af0dd58f9 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java @@ -0,0 +1,38 @@ +/* + * 2020 - NDTP v6 Protocol Encoder + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import java.nio.charset.StandardCharsets; +import org.traccar.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.model.Command; + +public class NDTPv6ProtocolEncoder extends BaseProtocolEncoder { + + public NDTPv6ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private ByteBuf encodeCommand(String commandString) { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeBytes(commandString.getBytes(StandardCharsets.US_ASCII)); + return buffer; + } + + @Override + protected Object encodeCommand(Command command) { + switch (command.getType()) { + case Command.TYPE_IDENTIFICATION: + return encodeCommand("BB+IDNT"); + case Command.TYPE_REBOOT_DEVICE: + return encodeCommand("BB+RESET"); + case Command.TYPE_POSITION_SINGLE: + return encodeCommand("BB+RRCD"); + default: + return null; + } + } +} -- cgit v1.2.3 From 3ac73dabfd5d9fb403c119574acd1581daa12b90 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Sep 2022 06:44:45 -0700 Subject: Add Thuraya protocol support --- setup/default.xml | 1 + .../java/org/traccar/protocol/ThurayaProtocol.java | 39 +++++ .../traccar/protocol/ThurayaProtocolDecoder.java | 195 +++++++++++++++++++++ .../protocol/ThurayaProtocolDecoderTest.java | 24 +++ 4 files changed, 259 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/ThurayaProtocol.java create mode 100644 src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 607efc35f..b1417bd95 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -284,5 +284,6 @@ 5239 5240 5241 + 5242 diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocol.java b/src/main/java/org/traccar/protocol/ThurayaProtocol.java new file mode 100644 index 000000000..f709a1183 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ThurayaProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class ThurayaProtocol extends BaseProtocol { + + @Inject + public ThurayaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); + pipeline.addLast(new ThurayaProtocolDecoder(ThurayaProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java new file mode 100644 index 000000000..a287ece34 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java @@ -0,0 +1,195 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; + +public class ThurayaProtocolDecoder extends BaseProtocolDecoder { + + public ThurayaProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_EVENT = 0x5101; + public static final int MSG_PERIODIC_REPORT = 0x7101; + public static final int MSG_SETTING_RESPONSE = 0x8115; + public static final int MSG_ACK = 0x9901; + + private static int checksum(ByteBuffer buf) { + int crc = 0; + while (buf.hasRemaining()) { + crc += buf.get(); + } + crc = ~crc; + crc += 1; + return crc; + } + + private void sendResponse(Channel channel, SocketAddress remoteAddress, long id, int type) { + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeCharSequence("#T", StandardCharsets.US_ASCII); + response.writeShort(15); // length + response.writeShort(MSG_ACK); + response.writeInt((int) id); + response.writeShort(type); + response.writeShort(1); // server ok + response.writeShort(checksum(response.nioBuffer())); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + } + + private void decodeLocation(ByteBuf buf, Position position) { + + position.setValid(true); + + DateBuilder dateBuilder = new DateBuilder(); + + int date = buf.readInt(); + dateBuilder.setDay(date % 100); + date /= 100; + dateBuilder.setMonth(date % 100); + date /= 100; + dateBuilder.setYear(date); + + int time = buf.readInt(); + dateBuilder.setSecond(time % 100); + time /= 100; + dateBuilder.setMinute(time % 100); + time /= 100; + dateBuilder.setHour(time); + + position.setTime(dateBuilder.getDate()); + + position.setLongitude(buf.readInt() / 1000000.0); + position.setLatitude(buf.readInt() / 1000000.0); + + int data = buf.readUnsignedShort(); + + int ignition = BitUtil.from(data, 12); + if (ignition == 1) { + position.set(Position.KEY_IGNITION, true); + } else if (ignition == 2) { + position.set(Position.KEY_IGNITION, false); + } + + position.setCourse(BitUtil.to(data, 12)); + position.setSpeed(buf.readShort()); + + position.set(Position.KEY_RPM, buf.readShort()); + + position.set("data", readString(buf)); + } + + private String decodeAlarm(int event) { + switch (event) { + case 10: + return Position.ALARM_VIBRATION; + case 11: + return Position.ALARM_OVERSPEED; + case 12: + return Position.ALARM_POWER_CUT; + case 13: + return Position.ALARM_LOW_BATTERY; + case 18: + return Position.ALARM_GPS_ANTENNA_CUT; + case 20: + return Position.ALARM_ACCELERATION; + case 21: + return Position.ALARM_BRAKING; + default: + return null; + } + } + + private String readString(ByteBuf buf) { + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); + CharSequence value = buf.readCharSequence(endIndex - buf.readerIndex(), StandardCharsets.US_ASCII); + buf.readUnsignedByte(); // delimiter + return value.toString(); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(2); // service + buf.readUnsignedShort(); // length + int type = buf.readUnsignedShort(); + long id = buf.readUnsignedInt(); + + sendResponse(channel, remoteAddress, id, type); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); + if (deviceSession == null) { + return null; + } + + if (type == MSG_EVENT) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(buf, position); + + int event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); + position.set("eventData", readString(buf)); + + return position; + + } else if (type == MSG_PERIODIC_REPORT) { + + List positions = new LinkedList<>(); + + int count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(buf, position); + + positions.add(position); + + } + + return positions; + + } + + return null; + } + +} diff --git a/src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java new file mode 100644 index 000000000..90431fa24 --- /dev/null +++ b/src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class ThurayaProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new ThurayaProtocolDecoder(null)); + + verifyPositions(decoder, binary( + "235400437101072bca3c0201348b9a00014c9f085493fc02200c5411470000000042323a300001348b9a00014d03085493ea02200c5010000000000042323a3000f2c1")); + + verifyPosition(decoder, binary( + "2354002b5101072bca3c01348b9a00013fba000000000000000010000000000042323a3000174f4e00f9de")); + + verifyNull(decoder, binary( + "235400d88115071e37d691030133342e3233362e3133302e3637000000001e56313030320030000700080102030405060708020101010101020201030103030302020000007800000078000004b000001c20050a64000015b3800015b374657374696e67003132333435360002010f28393031303539383938303134373738000043383a592c43373a592c43333a592c43323a592c43313a592c42353a592c42343a592c42323a592c42313a592c41323a592c41313a590045313a592c45373a590065746973616c61742e61650047455400322e3130d6de")); + + } + +} -- cgit v1.2.3 From e7a5d1e1f4d7746e35dfac5b15078de03dc7bf79 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Sep 2022 09:27:12 -0700 Subject: Support RFTRACK monitoring units --- setup/default.xml | 1 + .../java/org/traccar/protocol/RfTrackProtocol.java | 43 ++++++++ .../traccar/protocol/RfTrackProtocolDecoder.java | 115 +++++++++++++++++++++ .../protocol/RfTrackProtocolDecoderTest.java | 19 ++++ 4 files changed, 178 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/RfTrackProtocol.java create mode 100644 src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 098bdf95d..77561109c 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -287,5 +287,6 @@ 5242 5243 5244 + 5245 diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocol.java b/src/main/java/org/traccar/protocol/RfTrackProtocol.java new file mode 100644 index 000000000..d3b41e93e --- /dev/null +++ b/src/main/java/org/traccar/protocol/RfTrackProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class RfTrackProtocol extends BaseProtocol { + + @Inject + public RfTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(16384)); + pipeline.addLast(new RfTrackProtocolDecoder(RfTrackProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java new file mode 100644 index 000000000..540c3ce0b --- /dev/null +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -0,0 +1,115 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.QueryStringDecoder; +import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { + + public RfTrackProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpRequest request = (FullHttpRequest) msg; + QueryStringDecoder decoder = new QueryStringDecoder( + request.content().toString(StandardCharsets.US_ASCII), false); + Map> params = decoder.parameters(); + + Position position = new Position(getProtocolName()); + Network network = new Network(); + + for (Map.Entry> entry : params.entrySet()) { + for (String value : entry.getValue()) { + switch (entry.getKey()) { + case "i": + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + break; + case "v": + position.set(Position.KEY_VERSION_FW, value); + break; + case "t": + position.setDeviceTime(new Date(Long.parseLong(value))); + break; + case "bat": + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value) & 0xff); + break; + case "gps": + JsonObject location = Json.createReader(new StringReader(value)).readObject(); + position.setValid(true); + position.setAccuracy(location.getJsonNumber("a").doubleValue()); + position.setLongitude(location.getJsonNumber("x").doubleValue()); + position.setLatitude(location.getJsonNumber("y").doubleValue()); + position.setAltitude(location.getJsonNumber("z").doubleValue()); + position.setFixTime(new Date(location.getJsonNumber("t").longValue())); + break; + case "gsm": + JsonObject cellInfo = Json.createReader(new StringReader(value)).readObject(); + int mcc = cellInfo.getInt("c"); + int mnc = cellInfo.getInt("n"); + JsonArray cells = cellInfo.getJsonArray("b"); + for (int i = 0; i < cells.size(); i++) { + JsonObject cell = cells.getJsonObject(i); + network.addCellTower(CellTower.from( + mcc, mnc, cell.getInt("l"), cell.getInt("c"), cell.getInt("b"))); + } + break; + default: + break; + } + } + } + + if (position.getFixTime() == null) { + getLastLocation(position, position.getDeviceTime()); + } + + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + + sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer("{}", StandardCharsets.UTF_8)); + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java new file mode 100644 index 000000000..19a654fa6 --- /dev/null +++ b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpMethod; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class RfTrackProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new RfTrackProtocolDecoder(null)); + + verifyPosition(decoder, request(HttpMethod.POST, "/deviceDataUpload.do", + buffer("gsm={\"n\":0,\"b\":[{\"l\":6166,\"b\":19,\"c\":21423},{\"l\":6166,\"b\":18,\"c\":21416},{\"l\":6166,\"b\":17,\"c\":21383},{\"l\":6166,\"b\":13,\"c\":21422},{\"l\":6166,\"b\":13,\"c\":21435},{\"l\":6169,\"b\":11,\"c\":21311}],\"c\":460}&wifi=[{\"l\":-49,\"t\":\"lianqin20\"}]&mt=1073709094&i=358477047125172&gps={\"a\":30.0,\"y\":31.251563,\"s\":4,\"t\":1589764496654,\"z\":0.0,\"x\":121.360346}&dbm=-53&td=1589720501123&rc=0&bar=1001.85065&u_ids=[8441644.1,53036.1]&t=1589764500713&bat=12380&v=T2.142.2_2.0_R03&i_ids=[4247328.1,53036.1,10522408.1]&idt=140736414711817&id=39163"))); + + } + +} -- cgit v1.2.3 From 35fa03ecfbe0f2cc221665cba2538cf2dd155b34 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 11:36:08 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 6dcf6871a..0e7d77bce 100644 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.3", + "Implementation-Version": "5.4", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 3e946e672..66d2bd401 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.3 +AppVersion=5.4 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index acdc1053a..825e0d003 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.3", + "version": "5.4", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From 1a08e7cc2612539e6e16bb17b76a8d6866bb24f7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 15:50:39 -0800 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 3dcef5a8d..aa4ff41cd 100644 --- a/build.gradle +++ b/build.gradle @@ -101,7 +101,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.4", + "Implementation-Version": "5.5", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 66d2bd401..28b33adfb 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.4 +AppVersion=5.5 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 825e0d003..3eab9b522 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.4", + "version": "5.5", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From b274f55b7ba6128c714484460a81189105df516b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Dec 2022 11:31:49 -0800 Subject: Dedicated LocationIQ geocoder --- setup/default.xml | 3 +-- src/main/java/org/traccar/MainModule.java | 23 +++-------------- .../org/traccar/geocoder/LocationIqGeocoder.java | 29 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/traccar/geocoder/LocationIqGeocoder.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 77561109c..c00d29384 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -16,8 +16,7 @@ false true - nominatim - https://us1.locationiq.com/v1/reverse.php + locationiq pk.689d849289c8c63708068b2ff1f63b2d true true diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 6e59527bc..f3d04f634 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -42,25 +42,7 @@ import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; import org.traccar.forward.PositionForwarderKafka; import org.traccar.forward.PositionForwarderUrl; -import org.traccar.geocoder.AddressFormat; -import org.traccar.geocoder.BanGeocoder; -import org.traccar.geocoder.BingMapsGeocoder; -import org.traccar.geocoder.FactualGeocoder; -import org.traccar.geocoder.GeoapifyGeocoder; -import org.traccar.geocoder.GeocodeFarmGeocoder; -import org.traccar.geocoder.GeocodeXyzGeocoder; -import org.traccar.geocoder.Geocoder; -import org.traccar.geocoder.GisgraphyGeocoder; -import org.traccar.geocoder.GoogleGeocoder; -import org.traccar.geocoder.HereGeocoder; -import org.traccar.geocoder.MapQuestGeocoder; -import org.traccar.geocoder.MapTilerGeocoder; -import org.traccar.geocoder.MapboxGeocoder; -import org.traccar.geocoder.MapmyIndiaGeocoder; -import org.traccar.geocoder.NominatimGeocoder; -import org.traccar.geocoder.OpenCageGeocoder; -import org.traccar.geocoder.PositionStackGeocoder; -import org.traccar.geocoder.TomTomGeocoder; +import org.traccar.geocoder.*; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; @@ -183,6 +165,9 @@ public class MainModule extends AbstractModule { case "nominatim": geocoder = new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); break; + case "locationiq": + geocoder = new LocationIqGeocoder(client, url, key, language, cacheSize, addressFormat); + break; case "gisgraphy": geocoder = new GisgraphyGeocoder(client, url, cacheSize, addressFormat); break; diff --git a/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java b/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java new file mode 100644 index 000000000..f2ffe02d6 --- /dev/null +++ b/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java @@ -0,0 +1,29 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.geocoder; + +import javax.ws.rs.client.Client; + +public class LocationIqGeocoder extends NominatimGeocoder { + + private static final String DEFAULT_URL = "https://us1.locationiq.com/v1/reverse.php"; + + public LocationIqGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, url != null ? url : DEFAULT_URL, key, language, cacheSize, addressFormat); + } + +} -- cgit v1.2.3 From 250be2f49fe578b13ced80bbcf13a7b15b2f267e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Feb 2023 15:18:21 -0800 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 2b072f0f9..a7baaa336 100644 --- a/build.gradle +++ b/build.gradle @@ -101,7 +101,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.5", + "Implementation-Version": "5.6", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 28b33adfb..09b94ee5e 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.5 +AppVersion=5.6 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 3eab9b522..229296c1a 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.5", + "version": "5.6", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From d3291d6a7dc5d7ead326f27e97a841682a3aa20f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Feb 2023 15:26:46 -0800 Subject: Add missing JDK module --- setup/package.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setup') diff --git a/setup/package.sh b/setup/package.sh index 71b86014f..f17b5fb14 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -120,7 +120,7 @@ package_other () { package_windows () { info "Building Windows 64 installer" unzip -q OpenJDK*64_windows*.zip - jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre + jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec,jdk.unsupported --output out/jre rm -rf jdk-* wine app/ISCC.exe traccar.iss >/dev/null rm -rf out/jre @@ -134,7 +134,7 @@ package_linux () { cp traccar.service out tar -xf OpenJDK*$1_linux*.tar.gz - jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre + jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec,jdk.unsupported --output out/jre rm -rf jdk-* makeself --needroot --quiet --notemp out traccar.run "traccar" ./setup.sh rm -rf out/jre -- cgit v1.2.3 From 1439422c6f4ce947f6719743b37fa49f251fc97f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Feb 2023 11:30:26 -0800 Subject: Refactor notificator classes --- setup/default.xml | 2 +- .../traccar/api/resource/NotificationResource.java | 4 +-- .../org/traccar/database/NotificationManager.java | 4 +-- .../traccar/notification/NotificatorManager.java | 12 +++----- .../java/org/traccar/notificators/Notificator.java | 5 ++-- .../traccar/notificators/NotificatorFirebase.java | 8 ++--- .../org/traccar/notificators/NotificatorMail.java | 5 ++-- .../org/traccar/notificators/NotificatorNull.java | 34 ---------------------- .../traccar/notificators/NotificatorPushover.java | 5 ++-- .../org/traccar/notificators/NotificatorSms.java | 5 ++-- .../traccar/notificators/NotificatorTelegram.java | 5 ++-- .../traccar/notificators/NotificatorTraccar.java | 18 ++++++------ .../org/traccar/notificators/NotificatorWeb.java | 8 ++--- src/main/java/org/traccar/sms/HttpSmsClient.java | 4 +-- src/main/java/org/traccar/sms/SmsManager.java | 3 +- 15 files changed, 44 insertions(+), 78 deletions(-) delete mode 100644 src/main/java/org/traccar/notificators/NotificatorNull.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index c00d29384..75acf25a1 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -32,7 +32,7 @@ ./media - web,mail + web,mail,command https://www.traccar.org/analytics/ diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 2e4ad12f3..d58557601 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -83,7 +83,7 @@ public class NotificationResource extends ExtendedObjectResource { public Response testMessage() throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); for (Typed method : notificatorManager.getAllNotificatorTypes()) { - notificatorManager.getNotificator(method.getType()).send(user, new Event("test", 0), null); + notificatorManager.getNotificator(method.getType()).send(null, user, new Event("test", 0), null); } return Response.noContent().build(); } @@ -93,7 +93,7 @@ public class NotificationResource extends ExtendedObjectResource { public Response testMessage(@PathParam("notificator") String notificator) throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); - notificatorManager.getNotificator(notificator).send(user, new Event("test", 0), null); + notificatorManager.getNotificator(notificator).send(null, user, new Event("test", 0), null); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index cb971b082..32216dfc6 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -107,8 +107,8 @@ public class NotificationManager { cacheManager.getNotificationUsers(notification.getId(), event.getDeviceId()).forEach(user -> { for (String notificator : notification.getNotificatorsTypes()) { try { - notificatorManager.getNotificator(notificator).send(user, event, position); - } catch (MessageException | InterruptedException exception) { + notificatorManager.getNotificator(notificator).send(notification, user, event, position); + } catch (MessageException exception) { LOGGER.warn("Notification failed", exception); } } diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index 1d9f4f423..c3ee7b480 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,15 +17,13 @@ package org.traccar.notification; import com.google.inject.Injector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Typed; import org.traccar.notificators.Notificator; +import org.traccar.notificators.NotificatorCommand; import org.traccar.notificators.NotificatorFirebase; import org.traccar.notificators.NotificatorMail; -import org.traccar.notificators.NotificatorNull; import org.traccar.notificators.NotificatorPushover; import org.traccar.notificators.NotificatorSms; import org.traccar.notificators.NotificatorTelegram; @@ -43,9 +41,8 @@ import java.util.stream.Collectors; @Singleton public class NotificatorManager { - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorManager.class); - private static final Map> NOTIFICATORS_ALL = Map.of( + "command", NotificatorCommand.class, "web", NotificatorWeb.class, "mail", NotificatorMail.class, "sms", NotificatorSms.class, @@ -75,8 +72,7 @@ public class NotificatorManager { return notificator; } } - LOGGER.warn("Failed to get notificator {}", type); - return new NotificatorNull(); + throw new RuntimeException("Failed to get notificator " + type); } public Set getAllNotificatorTypes() { diff --git a/src/main/java/org/traccar/notificators/Notificator.java b/src/main/java/org/traccar/notificators/Notificator.java index 052365c7a..cf71141c0 100644 --- a/src/main/java/org/traccar/notificators/Notificator.java +++ b/src/main/java/org/traccar/notificators/Notificator.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,12 +17,13 @@ package org.traccar.notificators; import org.traccar.model.Event; +import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; public interface Notificator { - void send(User user, Event event, Position position) throws MessageException, InterruptedException; + void send(Notification notification, User user, Event event, Position position) throws MessageException; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 5ce2cbc0b..9fa2ebaf3 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,10 +26,10 @@ import com.google.firebase.messaging.Aps; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; import com.google.firebase.messaging.MulticastMessage; -import com.google.firebase.messaging.Notification; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; +import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; @@ -64,7 +64,7 @@ public class NotificatorFirebase implements Notificator { } @Override - public void send(User user, Event event, Position position) throws MessageException { + public void send(Notification notification, User user, Event event, Position position) throws MessageException { if (user.hasAttribute("notificationTokens")) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); @@ -72,7 +72,7 @@ public class NotificatorFirebase implements Notificator { List registrationTokens = Arrays.asList(user.getString("notificationTokens").split("[, ]")); MulticastMessage message = MulticastMessage.builder() - .setNotification(Notification.builder() + .setNotification(com.google.firebase.messaging.Notification.builder() .setTitle(shortMessage.getSubject()) .setBody(shortMessage.getBody()) .build()) diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 19fde6756..7f755f170 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ package org.traccar.notificators; import org.traccar.mail.MailManager; import org.traccar.model.Event; +import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; @@ -40,7 +41,7 @@ public class NotificatorMail implements Notificator { } @Override - public void send(User user, Event event, Position position) throws MessageException { + public void send(Notification notification, User user, Event event, Position position) throws MessageException { try { var fullMessage = notificationFormatter.formatMessage(user, event, position, "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); diff --git a/src/main/java/org/traccar/notificators/NotificatorNull.java b/src/main/java/org/traccar/notificators/NotificatorNull.java deleted file mode 100644 index ba9ade9c6..000000000 --- a/src/main/java/org/traccar/notificators/NotificatorNull.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.notificators; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.model.User; - -public class NotificatorNull implements Notificator { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorNull.class); - - @Override - public void send(User user, Event event, Position position) { - LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); - } - -} diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index e00db0579..703d86876 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2023 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; +import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; @@ -61,7 +62,7 @@ public class NotificatorPushover implements Notificator { } @Override - public void send(User user, Event event, Position position) { + public void send(Notification notification, User user, Event event, Position position) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); Message message = new Message(); diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index e37d10888..7ec47b156 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ package org.traccar.notificators; import org.traccar.database.StatisticsManager; import org.traccar.model.Event; +import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; @@ -43,7 +44,7 @@ public class NotificatorSms implements Notificator { } @Override - public void send(User user, Event event, Position position) throws MessageException, InterruptedException { + public void send(Notification notification, User user, Event event, Position position) throws MessageException { if (user.getPhone() != null) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); statisticsManager.registerSms(); diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 38e87c222..63d2bb717 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2021 Rafael Miquelino (rafaelmiquelino@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; +import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; @@ -85,7 +86,7 @@ public class NotificatorTelegram implements Notificator { } @Override - public void send(User user, Event event, Position position) { + public void send(Notification notification, User user, Event event, Position position) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); TextMessage message = new TextMessage(); diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 9ae39f975..e32229506 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2023 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ public class NotificatorTraccar implements Notificator { private final String url; private final String key; - public static class Notification { + public static class NotificationObject { @JsonProperty("title") private String title; @JsonProperty("body") @@ -50,7 +50,7 @@ public class NotificatorTraccar implements Notificator { @JsonProperty("registration_ids") private String[] tokens; @JsonProperty("notification") - private Notification notification; + private NotificationObject notification; } @Inject @@ -62,19 +62,19 @@ public class NotificatorTraccar implements Notificator { } @Override - public void send(User user, Event event, Position position) { + public void send(org.traccar.model.Notification notification, User user, Event event, Position position) { if (user.hasAttribute("notificationTokens")) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); - Notification notification = new Notification(); - notification.title = shortMessage.getSubject(); - notification.body = shortMessage.getBody(); - notification.sound = "default"; + NotificationObject item = new NotificationObject(); + item.title = shortMessage.getSubject(); + item.body = shortMessage.getBody(); + item.sound = "default"; Message message = new Message(); message.tokens = user.getString("notificationTokens").split("[, ]"); - message.notification = notification; + message.notification = item; client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index deabeade1..51884074e 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,6 +17,7 @@ package org.traccar.notificators; import org.traccar.model.Event; +import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; @@ -32,14 +33,13 @@ public final class NotificatorWeb implements Notificator { private final NotificationFormatter notificationFormatter; @Inject - public NotificatorWeb( - ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { + public NotificatorWeb(ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { this.connectionManager = connectionManager; this.notificationFormatter = notificationFormatter; } @Override - public void send(User user, Event event, Position position) { + public void send(Notification notification, User user, Event event, Position position) { Event copy = new Event(); copy.setId(event.getId()); diff --git a/src/main/java/org/traccar/sms/HttpSmsClient.java b/src/main/java/org/traccar/sms/HttpSmsClient.java index 51b161594..683022967 100644 --- a/src/main/java/org/traccar/sms/HttpSmsClient.java +++ b/src/main/java/org/traccar/sms/HttpSmsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -67,7 +67,7 @@ public class HttpSmsClient implements SmsManager { } private String prepareValue(String value) throws UnsupportedEncodingException { - return encode ? URLEncoder.encode(value, StandardCharsets.UTF_8.name()) : value; + return encode ? URLEncoder.encode(value, StandardCharsets.UTF_8) : value; } private String preparePayload(String destAddress, String message) { diff --git a/src/main/java/org/traccar/sms/SmsManager.java b/src/main/java/org/traccar/sms/SmsManager.java index 9ab25d9cb..8cf99c9e8 100644 --- a/src/main/java/org/traccar/sms/SmsManager.java +++ b/src/main/java/org/traccar/sms/SmsManager.java @@ -20,7 +20,6 @@ import org.traccar.notification.MessageException; public interface SmsManager { - void sendMessage( - String destAddress, String message, boolean command) throws InterruptedException, MessageException; + void sendMessage(String destAddress, String message, boolean command) throws MessageException; } -- cgit v1.2.3 From 13b6eda9f0808bd829f31c589b90d10296b51a19 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Feb 2023 09:24:25 -0800 Subject: Add arm64 support --- setup/package.sh | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'setup') diff --git a/setup/package.sh b/setup/package.sh index f17b5fb14..cbfe03cae 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -15,6 +15,7 @@ usage () { echo "Available platforms:" echo " * linux-64" echo " * linux-arm" + echo " * linux-arm64" echo " * windows-64" echo " * other" exit 1 @@ -64,15 +65,18 @@ if [ $PLATFORM = "all" -o $PLATFORM = "windows-64" ]; then check_requirement "Windows 64 Java" "ls OpenJDK*64_windows*.zip" "Missing Windows 64 JDK (https://adoptium.net/)" check_requirement "Wine" "which wine" "Missing wine binary" fi -if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" -o $PLATFORM = "linux-arm" ]; then +if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" -o $PLATFORM = "linux-arm" -o $PLATFORM = "linux-arm64" ]; then check_requirement "Makeself" "which makeself" "Missing makeself binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" ]; then - check_requirement "Linux 64 Java" "ls OpenJDK*64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" + check_requirement "Linux 64 Java" "ls OpenJDK*x64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm" ]; then check_requirement "Linux ARM Java" "ls OpenJDK*arm_linux*.tar.gz" "Missing Linux ARM JDK (https://adoptium.net/)" fi +if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm64" ]; then + check_requirement "Linux 64 Java" "ls OpenJDK*aarch64_linux*.tar.gz" "Missing Linux ARM 64 JDK (https://adoptium.net/)" +fi if [ $PREREQ = false ]; then info "Missing build requirements, aborting..." exit 1 @@ -133,7 +137,7 @@ package_linux () { cp setup.sh out cp traccar.service out - tar -xf OpenJDK*$1_linux*.tar.gz + tar -xf OpenJDK*$2_linux*.tar.gz jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec,jdk.unsupported --output out/jre rm -rf jdk-* makeself --needroot --quiet --notemp out traccar.run "traccar" ./setup.sh @@ -148,22 +152,29 @@ package_linux () { package_linux_64 () { info "Building Linux 64 installer" - package_linux 64 + package_linux 64 x64 ok "Created Linux 64 installer" } package_linux_arm () { info "Building Linux ARM installer" - package_linux arm + package_linux arm arm ok "Created Linux ARM installer" } +package_linux_arm64 () { + info "Building Linux ARM 64 installer" + package_linux arm64 aarch64 + ok "Created Linux ARM 64 installer" +} + prepare case $PLATFORM in all) package_linux_64 package_linux_arm + package_linux_arm64 package_windows package_other ;; @@ -176,6 +187,10 @@ case $PLATFORM in package_linux_arm ;; + linux-arm64) + package_linux_arm64 + ;; + windows-64) package_windows ;; -- cgit v1.2.3 From a88fec16c1b8b2c3592e9d0a8b52ada6e038a81a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Feb 2023 09:36:39 -0800 Subject: Fix release build job --- .github/workflows/release.yml | 1 + setup/package.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'setup') diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0a9fb2e73..a157037a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,6 +50,7 @@ jobs: wget -q https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6+10/OpenJDK17U-jdk_x64_windows_hotspot_17.0.6_10.zip wget -q https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6+10/OpenJDK17U-jdk_x64_linux_hotspot_17.0.6_10.tar.gz wget -q https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6+10/OpenJDK17U-jdk_arm_linux_hotspot_17.0.6_10.tar.gz + wget -q https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6+10/OpenJDK17U-jdk_aarch64_linux_hotspot_17.0.6_10.tar.gz ./package.sh ${{ github.event.inputs.version }} - name: Upload installers working-directory: ./setup diff --git a/setup/package.sh b/setup/package.sh index cbfe03cae..f8ec927eb 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -75,7 +75,7 @@ if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm" ]; then check_requirement "Linux ARM Java" "ls OpenJDK*arm_linux*.tar.gz" "Missing Linux ARM JDK (https://adoptium.net/)" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm64" ]; then - check_requirement "Linux 64 Java" "ls OpenJDK*aarch64_linux*.tar.gz" "Missing Linux ARM 64 JDK (https://adoptium.net/)" + check_requirement "Linux ARM 64 Java" "ls OpenJDK*aarch64_linux*.tar.gz" "Missing Linux ARM 64 JDK (https://adoptium.net/)" fi if [ $PREREQ = false ]; then info "Missing build requirements, aborting..." -- cgit v1.2.3 From 5284faae8ce9ed077035167063c8d2977d06a8fd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 26 Feb 2023 10:49:24 -0800 Subject: Add cloud-init example --- setup/cloud-init.yaml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 setup/cloud-init.yaml (limited to 'setup') diff --git a/setup/cloud-init.yaml b/setup/cloud-init.yaml new file mode 100644 index 000000000..4ca2e3ed2 --- /dev/null +++ b/setup/cloud-init.yaml @@ -0,0 +1,29 @@ +#cloud-config + +write_files: + - content: | + + + + + ./conf/default.xml + + com.mysql.jdbc.Driver + jdbc:mysql://localhost/traccar?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8&sessionVariables=sql_mode='' + root + root + + + path: /root/traccar.xml + +package_update: true +packages: + - unzip + - mysql-server + +runcmd: + - mysql -u root --execute="ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root'; GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES; CREATE DATABASE traccar;" + - wget https://www.traccar.org/download/traccar-linux-64-latest.zip + - unzip traccar-linux-*.zip && ./traccar.run + - cp /root/traccar.xml /opt/traccar/conf/ + - service traccar start -- cgit v1.2.3 From ac60477392048413d97a6d54a4456647aaaf7d22 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 26 Mar 2023 09:55:07 -0700 Subject: Implement VLT protocol --- gradle/checkstyle.xml | 2 +- setup/default.xml | 1 + .../java/org/traccar/protocol/VltProtocol.java | 43 +++++++ .../org/traccar/protocol/VltProtocolDecoder.java | 137 +++++++++++++++++++++ .../traccar/protocol/VltProtocolDecoderTest.java | 22 ++++ 5 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/traccar/protocol/VltProtocol.java create mode 100644 src/main/java/org/traccar/protocol/VltProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/VltProtocolDecoderTest.java (limited to 'setup') diff --git a/gradle/checkstyle.xml b/gradle/checkstyle.xml index a6a6f0ff7..bb89450d6 100644 --- a/gradle/checkstyle.xml +++ b/gradle/checkstyle.xml @@ -114,7 +114,7 @@ - + diff --git a/setup/default.xml b/setup/default.xml index 75acf25a1..ff8ecf589 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -287,5 +287,6 @@ 5243 5244 5245 + 5246 diff --git a/src/main/java/org/traccar/protocol/VltProtocol.java b/src/main/java/org/traccar/protocol/VltProtocol.java new file mode 100644 index 000000000..ebced83b1 --- /dev/null +++ b/src/main/java/org/traccar/protocol/VltProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class VltProtocol extends BaseProtocol { + + @Inject + public VltProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(65535)); + pipeline.addLast(new VltProtocolDecoder(VltProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/VltProtocolDecoder.java b/src/main/java/org/traccar/protocol/VltProtocolDecoder.java new file mode 100644 index 000000000..8890dece1 --- /dev/null +++ b/src/main/java/org/traccar/protocol/VltProtocolDecoder.java @@ -0,0 +1,137 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.QueryStringDecoder; +import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Pattern; + +public class VltProtocolDecoder extends BaseHttpProtocolDecoder { + + public VltProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .number("(dd)") // alert id + .expression("([HL])") // history + .number("([01])") // validity + .number("(dd)(dd)(dd)") // date (ddmmyy) + .number("(dd)(dd)(dd)") // time (hhmmss) + .number("(d{3}.d{6})([NS])") // latitude + .number("(d{3}.d{6})([EW])") // longitude + .number("(d{3})") // mcc + .expression("(x*[0-9]+)") // mnc + .number("(x{4})") // lac + .number("(d{9})") // cid + .number("(d{3}.d{2})") // speed + .number("(d{3}.d{2})") // course + .number("(d{2})") // satellites + .number("(d{2})") // hdop + .number("(d{2})") // rssi + .number("([01])") // ignition + .number("([01])") // charging + .expression("([HMS])") // vehicle mode + .compile(); + + private Position decodePosition(DeviceSession deviceSession, String sentence) { + + Parser parser = new Parser(PATTERN, sentence); + if (!parser.matches()) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_EVENT, parser.nextInt()); + position.set(Position.KEY_ARCHIVE, parser.next().equals("H") ? true : null); + + position.setValid(parser.nextInt() > 0); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + + int mcc = parser.nextInt(); + int mnc = Integer.parseInt(parser.next().replaceAll("x", "")); + int lac = parser.nextHexInt(); + int cid = parser.nextInt(); + + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_HDOP, parser.nextInt()); + + position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid, parser.nextInt()))); + + position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + position.set(Position.KEY_CHARGE, parser.nextInt() > 0); + position.set(Position.KEY_MOTION, parser.next().equals("M")); + + return position; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpRequest request = (FullHttpRequest) msg; + QueryStringDecoder decoder = new QueryStringDecoder( + request.content().toString(StandardCharsets.US_ASCII), false); + String sentence = decoder.parameters().get("vltdata").iterator().next(); + + int index = 0; + String type = sentence.substring(index, index += 3); + String imei = sentence.substring(index, index += 15); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + + sendResponse(channel, HttpResponseStatus.OK); + + switch (type) { + case "NRM": + return decodePosition(deviceSession, sentence.substring(3 + 15)); + default: + List positions = new LinkedList<>(); + int count = Integer.parseInt(sentence.substring(index, index += 3)); + for (int i = 0; i < count; i++) { + positions.add(decodePosition(deviceSession, sentence.substring(index, index += 78))); + } + return positions; + } + } + +} diff --git a/src/test/java/org/traccar/protocol/VltProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/VltProtocolDecoderTest.java new file mode 100644 index 000000000..e0e88b324 --- /dev/null +++ b/src/test/java/org/traccar/protocol/VltProtocolDecoderTest.java @@ -0,0 +1,22 @@ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpMethod; +import org.junit.jupiter.api.Test; +import org.traccar.ProtocolTest; + +public class VltProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new VltProtocolDecoder(null)); + + verifyPosition(decoder, request(HttpMethod.POST, "/", + buffer("vltdata=NRM12345678901234501L1060418102230023.125503N080.068033E4041231234123456789070.48120.5025273011M"))); + + verifyPositions(decoder, request(HttpMethod.POST, "/", + buffer("vltdata=BTH86123004167306301301L1240323181909009.226018N076.794980E404x19601d000037596000.00198.7013011401S02H1240323181807009.226018N076.794980E404x72090a000000000000.00198.7013011101S02H1240323181707009.226018N076.794980E404x72090a000014598000.00198.7013011101S02H1240323181605009.226018N076.794982E404x72090a000014596000.00198.7013011101S02H1240323181504009.226018N076.794982E404x72090a000014596000.00198.7013010901S02H1240323181402009.226018N076.794980E404x72090a000014596001.67198.0013021301S02H1240323181306009.226010N076.794980E404x72090a000014596000.00174.0013021401S02H1240323181155009.226010N076.794980E404x72090a088511008000.00174.0013011201S02H1240323181057009.226010N076.794980E404x72090a000014596000.00174.0013011201S02H1240323180958009.226010N076.794980E404x72090a000014596000.00174.0013021401S02H1240323180858009.226010N076.794980E404x72090a000014596001.48174.0013021201S02H1240323180755009.226005N076.794982E404x72090a000014598000.00164.4013011301S02H1240323180652009.226005N076.794982E404x72090a000014598000.00164.4013021101S"))); + + } + +} -- cgit v1.2.3 From 7b3aebb26d1f1ed8617db2b03e5c35a48bf44dba Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 16 Apr 2023 09:55:52 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index da9c92ba9..1fa3986fd 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.6", + "Implementation-Version": "5.7", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 09b94ee5e..821c90958 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.6 +AppVersion=5.7 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 39bd6bd61..dde673e19 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.6", + "version": "5.7", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From 0e8057c605e38ecae49c6c69941a46075507302a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 18 May 2023 07:55:34 -0700 Subject: Clean up TranSync decoder --- setup/default.xml | 1 + .../org/traccar/protocol/TranSyncProtocol.java | 5 +- .../traccar/protocol/TranSyncProtocolDecoder.java | 227 +++++++-------------- .../protocol/TranSyncProtocolDecoderTest.java | 8 +- 4 files changed, 89 insertions(+), 152 deletions(-) (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index ff8ecf589..e8dc7aa79 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -288,5 +288,6 @@ 5244 5245 5246 + 5247 diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocol.java b/src/main/java/org/traccar/protocol/TranSyncProtocol.java index 5422380b6..fcc02a781 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocol.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2023 Anton Tananaev (anton@traccar.org) + * Copyright 2023 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,9 +30,10 @@ public class TranSyncProtocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0, true)); + pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); pipeline.addLast(new TranSyncProtocolDecoder(TranSyncProtocol.this)); } }); } + } diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index 130c916b1..816b5d2cf 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2023 Anton Tananaev (anton@traccar.org) + * Copyright 2023 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,118 +29,32 @@ import org.traccar.model.Position; import org.traccar.session.DeviceSession; import java.net.SocketAddress; -import java.util.Arrays; public class TranSyncProtocolDecoder extends BaseProtocolDecoder { - private static final byte[] STX = new byte[]{0x3a, 0x3a}; - - private String getHardwareType(int type) { - - switch (type) { - case 1: - return "basic"; - case 2: - return "asset"; - case 3: - return "bike"; - case 4: - return "serial"; - case 5: - return "obd"; - case 6: - return "l1"; - case 7: - return "ais-140"; - default: - return "unknown"; - } - } - public TranSyncProtocolDecoder(Protocol protocol) { super(protocol); } - protected void decodeAlarm(Position position, int value) { + private String decodeAlarm(int value) { switch (value) { + case 4: + return Position.ALARM_LOW_BATTERY; + case 6: + return Position.ALARM_POWER_RESTORED; case 10: - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case 11: - position.set(Position.KEY_EVENT, 11); - break; - case 16: - position.set(Position.KEY_EVENT, 16); - break; - case 3: - position.set(Position.KEY_ALARM, 3); - break; - case 22: - position.set(Position.KEY_ALARM, 22); - break; - case 9: - position.set(Position.KEY_EVENT, 9); - case 17: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; + return Position.ALARM_SOS; case 13: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; + return Position.ALARM_BRAKING; case 14: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 15: - position.set(Position.KEY_EVENT, 15); - break; + return Position.ALARM_ACCELERATION; + case 17: + return Position.ALARM_OVERSPEED; case 23: - position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); - break; - case 12: - position.set(Position.KEY_EVENT, 12); - break; - case 6: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case 4: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case 5: - position.set(Position.KEY_EVENT, 5); - break; + return Position.ALARM_ACCIDENT; default: - position.set(Position.KEY_EVENT, "unknown"); - } - } - private void analizeNegativePosition(Position position, int value) { - - if (!BitUtil.check(value, 1)) { - position.setLatitude(-position.getLatitude()); // 0/1 S/N - } - if (!BitUtil.check(value, 2)) { - position.setLongitude(-position.getLongitude()); // 0/1 W/E - } - } - - private void decodePowerEngineParameters(Position position, int value) { - - position.set(Position.PREFIX_OUT + 1, BitUtil.check(value, 7)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(value, 6)); - position.set(Position.PREFIX_IN + 3, BitUtil.check(value, 5)); - if (BitUtil.check(value, 4)) { - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - } - position.set(Position.KEY_IGNITION, BitUtil.check(value, 3)); - position.set("gpsFix", BitUtil.check(value, 0)); - } - - private void decodeTrackerStatusParameters(Position position, int value) { - if (BitUtil.check(value, 7)) { - position.set(Position.KEY_ARCHIVE, true); - } - if (BitUtil.check(value, 5)) { - position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); + return null; } - position.set(Position.KEY_VERSION_HW, getHardwareType(BitUtil.between(value, 0, 3))); } @Override @@ -148,88 +62,105 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; - if (Arrays.equals(ByteBufUtil.getBytes(buf, 0, 2), STX)) { - buf.readUnsignedShort(); - } - buf.readByte(); //packetLength - - int locationAreaCode = buf.readUnsignedShort(); - String deviceId = ByteBufUtil.hexDump(buf.readSlice(8)); + buf.readUnsignedShort(); // header + buf.readByte(); // length - buf.readUnsignedShort(); //informationSerialNumber - buf.readUnsignedByte(); //protocolNumber + int lac = buf.readUnsignedShort(); + String deviceId = ByteBufUtil.hexDump(buf.readSlice(8)); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId); if (deviceSession == null) { return null; } + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setValid(true); + + buf.readUnsignedShort(); // index + buf.readUnsignedByte(); // type + position.setTime(new DateBuilder() .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .getDate()); - position.setLatitude(buf.readUnsignedInt() / 1800000.0); - position.setLongitude(buf.readUnsignedInt() / 1800000.0); + + double latitude = buf.readUnsignedInt() / 1800000.0; + double longitude = buf.readUnsignedInt() / 1800000.0; + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); position.setCourse(buf.readUnsignedShort()); - int mobileNetworkCode = buf.readUnsignedByte(); - int cellTowerId = buf.readUnsignedShort(); - int statusParameters = buf.readUnsignedByte(); + int mnc = buf.readUnsignedByte(); + int cid = buf.readUnsignedShort(); + int status0 = buf.readUnsignedByte(); - decodePowerEngineParameters(position, statusParameters); - analizeNegativePosition(position, statusParameters); + position.setValid(BitUtil.check(status0, 0)); + position.setLatitude(BitUtil.check(status0, 1) ? latitude : -latitude); + position.setLongitude(BitUtil.check(status0, 2) ? longitude : -longitude); + + position.set(Position.PREFIX_OUT + 1, BitUtil.check(status0, 7)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(status0, 6)); + position.set(Position.PREFIX_IN + 3, BitUtil.check(status0, 5)); + if (BitUtil.check(status0, 4)) { + position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); + } + position.set(Position.KEY_IGNITION, BitUtil.check(status0, 3)); buf.readUnsignedByte(); // reserved - decodeAlarm(position, buf.readUnsignedByte()); + int event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); - decodeTrackerStatusParameters(position, buf.readUnsignedByte()); + int status3 = buf.readUnsignedByte(); + if (BitUtil.check(status3, 7)) { + position.set(Position.KEY_ARCHIVE, true); + } + if (BitUtil.check(status3, 5)) { + position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); + } - int gsmSignalStrength = buf.readUnsignedByte(); + int rssi = buf.readUnsignedByte(); + CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); + cellTower.setMobileNetworkCode(mnc); + cellTower.setSignalStrength(rssi); + position.setNetwork(new Network(cellTower)); position.set(Position.KEY_BATTERY, (double) (buf.readUnsignedByte() / 10)); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.set(Position.KEY_HDOP, buf.readUnsignedByte()); position.set(Position.PREFIX_ADC + 1, (short) buf.readUnsignedShort()); - CellTower cellTower = CellTower.fromLacCid(getConfig(), locationAreaCode, cellTowerId); - cellTower.setMobileNetworkCode(mobileNetworkCode); - cellTower.setSignalStrength(gsmSignalStrength); - - position.setNetwork(new Network(cellTower)); - if (buf.readableBytes() > 5) { - buf.readUnsignedByte(); // odometerIndex - int odometerLength = buf.readUnsignedByte(); - if (odometerLength > 0) { - int odometer = buf.readBytes(odometerLength).readInt(); - position.set(Position.KEY_ODOMETER, odometer); + buf.readUnsignedByte(); // odometer id + int length = buf.readUnsignedByte(); + if (length > 0) { + position.set(Position.KEY_ODOMETER, buf.readBytes(length).readInt()); } - if ((buf.readableBytes() > 5)) { - buf.readUnsignedByte(); // tagIndex - int tagLength = buf.readUnsignedByte(); - if (tagLength > 0) { - position.set("tag", ByteBufUtil.hexDump(buf.readSlice(tagLength))); - } + } + if (buf.readableBytes() > 5) { + buf.readUnsignedByte(); // rfid id + int length = buf.readUnsignedByte(); + if (length > 0) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(length))); } - if ((buf.readableBytes() > 5)) { - buf.readUnsignedByte(); // adc2Index - int adc2Length = buf.readUnsignedByte(); - if (adc2Length > 0) { - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - } + } + if (buf.readableBytes() > 5) { + buf.readUnsignedByte(); // adc2 id + int length = buf.readUnsignedByte(); + if (length > 0) { + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); } - if ((buf.readableBytes() > 5)) { - buf.readUnsignedByte(); // adc3Index - int adc2Length = buf.readUnsignedByte(); - if (adc2Length > 0 && adc2Length <= buf.readableBytes() - 2) { - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort()); - } + } + if (buf.readableBytes() > 5) { + buf.readUnsignedByte(); // adc3 id + int length = buf.readUnsignedByte(); + if (length > 0 && length <= buf.readableBytes() - 2) { + position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort()); } } + return position; } + } diff --git a/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java index c84ae2e0f..27f53b574 100644 --- a/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java @@ -10,8 +10,12 @@ public class TranSyncProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TranSyncProtocolDecoder(null)); - verifyPosition(decoder, binary("3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000100000050252ee060200822323")); + verifyPosition(decoder, binary( + "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000100000050252ee060200822323")); + + verifyAttributes(decoder, binary( + "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000000000050252ee060200822323")); - verifyAttributes(decoder, binary("3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000000000050252ee060200822323")); } + } -- cgit v1.2.3 From 48dae92ed4cda1acdb76f0a9250f545f3bca977a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 19 May 2023 15:28:06 -0700 Subject: Update MySQL URL --- setup/cloud-init.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup') diff --git a/setup/cloud-init.yaml b/setup/cloud-init.yaml index 4ca2e3ed2..1246fb1b7 100644 --- a/setup/cloud-init.yaml +++ b/setup/cloud-init.yaml @@ -9,7 +9,7 @@ write_files: ./conf/default.xml com.mysql.jdbc.Driver - jdbc:mysql://localhost/traccar?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8&sessionVariables=sql_mode='' + jdbc:mysql://localhost/traccar?zeroDateTimeBehavior=round&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8&sessionVariables=sql_mode='' root root -- cgit v1.2.3 From 4b7e7537029b3e3f5f05168f063a4f71b987405b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 May 2023 13:53:23 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setup') diff --git a/build.gradle b/build.gradle index 9dba72db2..727d2342e 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.7", + "Implementation-Version": "5.8", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 821c90958..f9988a6f3 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.7 +AppVersion=5.8 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 889728d33..eec852ac7 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.7", + "version": "5.8", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From 44527107b2bd5798356d6639573d3ccea67fd3b4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 3 Jul 2023 13:54:19 -0700 Subject: Initial T622G-F9 Iridium support --- setup/default.xml | 1 + .../org/traccar/protocol/T622IridiumProtocol.java | 39 +++++++++ .../protocol/T622IridiumProtocolDecoder.java | 93 ++++++++++++++++++++++ .../protocol/T622IridiumProtocolDecoderTest.java | 20 +++++ 4 files changed, 153 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/T622IridiumProtocol.java create mode 100644 src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index e8dc7aa79..576bfcb6c 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -289,5 +289,6 @@ 5245 5246 5247 + 5248 diff --git a/src/main/java/org/traccar/protocol/T622IridiumProtocol.java b/src/main/java/org/traccar/protocol/T622IridiumProtocol.java new file mode 100644 index 000000000..1289fe8e7 --- /dev/null +++ b/src/main/java/org/traccar/protocol/T622IridiumProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class T622IridiumProtocol extends BaseProtocol { + + @Inject + public T622IridiumProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2)); + pipeline.addLast(new T622IridiumProtocolDecoder(T622IridiumProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java new file mode 100644 index 000000000..6a81a452a --- /dev/null +++ b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java @@ -0,0 +1,93 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +public class T622IridiumProtocolDecoder extends BaseProtocolDecoder { + + public T622IridiumProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.readUnsignedByte(); // protocol revision + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // header indicator + buf.readUnsignedShort(); // header length + buf.readUnsignedInt(); // reference + + String imei = buf.readCharSequence(15, StandardCharsets.US_ASCII).toString(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { + return null; + } + + buf.readUnsignedByte(); // session status + buf.readUnsignedShort(); // originator index + buf.readUnsignedShort(); // transfer index + buf.readUnsignedInt(); // session time + buf.readUnsignedByte(); // payload indicator + buf.readUnsignedShort(); // payload length + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + + position.setLatitude(buf.readIntLE() / 1000000.0); + position.setLongitude(buf.readIntLE() / 1000000.0); + position.setTime(new Date((buf.readUnsignedIntLE() + 946713600) * 1000)); + position.setValid(buf.readUnsignedByte() > 0); + + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + position.setCourse(buf.readUnsignedShortLE()); + + position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + + position.setAltitude(buf.readShortLE()); + + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 1000); + position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); + + buf.readUnsignedByte(); // geofence + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java new file mode 100644 index 000000000..4bc79fbe8 --- /dev/null +++ b/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java @@ -0,0 +1,20 @@ +package org.traccar.protocol; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.traccar.ProtocolTest; + +public class T622IridiumProtocolDecoderTest extends ProtocolTest { + + @Disabled + @Test + public void testDecode() throws Exception { + + var decoder = inject(new T622IridiumProtocolDecoder(null)); + + verifyPosition(decoder, binary( + "01003301001c2a8cef8333303034333430363735343836353000001700006461d512020011232f03a0fff1c85d0612b3f02b00000048")); + + } + +} -- cgit v1.2.3