From 45bbb7a78a1312eb42e331e22478874d13e7a505 Mon Sep 17 00:00:00 2001 From: casswarry0 Date: Tue, 23 Nov 2021 20:09:32 -0700 Subject: Add additional status codes to eeLink protocol --- .../java/org/traccar/protocol/EelinkProtocolDecoder.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 8fe12fe69..068b19cbc 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -232,9 +232,20 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { int status = buf.readUnsignedShort(); position.setValid(BitUtil.check(status, 0)); - if (BitUtil.check(status, 1)) { + if (BitUtil.check(status, 1)) { // designed for car position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); } + if (BitUtil.check(status, 3)) { // accelerometer supported + position.set(Position.KEY_ARMED, BitUtil.check(status, 4)); + position.set(Position.KEY_MOTION, BitUtil.check(status, 9)); + } + if (BitUtil.check(status, 5)) { // relay control supported + position.set(Position.KEY_BLOCKED, BitUtil.check(status, 6)); + } + if (BitUtil.check(status, 7)) { // external charging supported + position.set(Position.KEY_CHARGE, BitUtil.check(status, 8)); + } + position.set(Position.KEY_GPS, BitUtil.check(status, 10)); position.set(Position.KEY_STATUS, status); } -- cgit v1.2.3 From 9ec2d09ad8a757d58f70812b9cf5e835321382e6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Feb 2022 17:33:58 -0800 Subject: Migrate permissions to storage --- debug.xml | 1 + gradle/checkstyle.xml | 4 +- src/main/java/org/traccar/MainModule.java | 5 - .../java/org/traccar/api/BaseObjectResource.java | 105 ++++------------ src/main/java/org/traccar/api/BaseResource.java | 12 +- .../org/traccar/api/ExtendedObjectResource.java | 51 ++++---- src/main/java/org/traccar/api/MediaFilter.java | 6 +- .../java/org/traccar/api/SimpleObjectResource.java | 30 +++-- .../org/traccar/api/resource/DeviceResource.java | 4 +- .../org/traccar/api/resource/EventResource.java | 18 +-- .../traccar/api/resource/NotificationResource.java | 3 +- .../org/traccar/api/resource/PositionResource.java | 2 +- .../org/traccar/api/resource/ReportResource.java | 20 +-- .../traccar/api/security/PermissionsService.java | 136 +++++++++++++++++++++ src/main/java/org/traccar/config/Keys.java | 7 ++ .../java/org/traccar/database/DeviceManager.java | 3 +- .../org/traccar/database/PermissionsManager.java | 22 ---- src/main/java/org/traccar/model/Permission.java | 2 +- src/main/java/org/traccar/model/User.java | 6 + .../java/org/traccar/storage/DatabaseStorage.java | 57 +++++++-- .../java/org/traccar/storage/MemoryStorage.java | 5 +- .../java/org/traccar/storage/QueryBuilder.java | 20 +-- src/main/java/org/traccar/storage/Storage.java | 17 ++- .../java/org/traccar/storage/query/Condition.java | 38 ++++++ 24 files changed, 375 insertions(+), 199 deletions(-) create mode 100644 src/main/java/org/traccar/api/security/PermissionsService.java (limited to 'src/main/java/org') diff --git a/debug.xml b/debug.xml index f9515bb2b..941b849bb 100644 --- a/debug.xml +++ b/debug.xml @@ -11,6 +11,7 @@ true true + true org.h2.Driver jdbc:h2:./target/database diff --git a/gradle/checkstyle.xml b/gradle/checkstyle.xml index 9d30e53d6..6cff6ffa5 100644 --- a/gradle/checkstyle.xml +++ b/gradle/checkstyle.xml @@ -122,7 +122,9 @@ - + + + diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 842f7e3ce..79cfcc0a8 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -444,9 +444,4 @@ public class MainModule extends AbstractModule { return GlobalTimer.getTimer(); } - @Override - protected void configure() { - binder().requireExplicitBindings(); - } - } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 22756f62a..07c74449c 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,70 +16,44 @@ */ package org.traccar.api; -import java.sql.SQLException; -import java.util.Set; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.Response; - import org.traccar.Context; import org.traccar.database.BaseObjectManager; import org.traccar.database.ExtendedObjectManager; -import org.traccar.database.ManagableObjects; import org.traccar.database.SimpleObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.GroupedModel; -import org.traccar.model.ScheduledModel; +import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; public abstract class BaseObjectResource extends BaseResource { - private final Class baseClass; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { this.baseClass = baseClass; } - protected final Class getBaseClass() { - return baseClass; - } - - protected final Set getSimpleManagerItems(BaseObjectManager manager, boolean all, long userId) { - Set result; - if (all) { - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = manager.getAllItems(); - } else { - Context.getPermissionsManager().checkManager(getUserId()); - result = ((ManagableObjects) manager).getManagedItems(getUserId()); - } - } else { - if (userId == 0) { - userId = getUserId(); - } - Context.getPermissionsManager().checkUser(getUserId(), userId); - result = ((ManagableObjects) manager).getUserItems(userId); - } - return result; - } - @Path("{id}") @GET - public Response getSingle(@PathParam("id") long id) throws SQLException { - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), id); - BaseObjectManager manager = Context.getManager(baseClass); - T entity = manager.getById(id); + public Response getSingle(@PathParam("id") long id) throws StorageException { + permissionsService.checkPermission(baseClass, getUserId(), id); + T entity = storage.getObject(baseClass, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); if (entity != null) { return Response.ok(entity).build(); } else { @@ -89,25 +63,13 @@ public abstract class BaseObjectResource extends BaseResour @POST public Response add(T entity) throws StorageException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - Context.getPermissionsManager().checkDeviceLimit(getUserId()); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } else if (entity instanceof GroupedModel && ((GroupedModel) entity).getGroupId() != 0) { - Context.getPermissionsManager().checkPermission( - Group.class, getUserId(), ((GroupedModel) entity).getGroupId()); - } else if (entity instanceof ScheduledModel && ((ScheduledModel) entity).getCalendarId() != 0) { - Context.getPermissionsManager().checkPermission( - Calendar.class, getUserId(), ((ScheduledModel) entity).getCalendarId()); - } + permissionsService.checkEdit(getUserId(), entity, true); BaseObjectManager manager = Context.getManager(baseClass); manager.addItem(entity); LogAction.create(getUserId(), entity); - Context.getDataManager().linkObject(User.class, getUserId(), baseClass, entity.getId(), true); + storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); if (manager instanceof SimpleObjectManager) { @@ -122,22 +84,8 @@ public abstract class BaseObjectResource extends BaseResour @Path("{id}") @PUT public Response update(T entity) throws StorageException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - } else if (baseClass.equals(User.class)) { - User before = Context.getPermissionsManager().getUser(entity.getId()); - Context.getPermissionsManager().checkUserUpdate(getUserId(), before, (User) entity); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } else if (entity instanceof GroupedModel && ((GroupedModel) entity).getGroupId() != 0) { - Context.getPermissionsManager().checkPermission( - Group.class, getUserId(), ((GroupedModel) entity).getGroupId()); - } else if (entity instanceof ScheduledModel && ((ScheduledModel) entity).getCalendarId() != 0) { - Context.getPermissionsManager().checkPermission( - Calendar.class, getUserId(), ((ScheduledModel) entity).getCalendarId()); - } - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), entity.getId()); + permissionsService.checkEdit(getUserId(), entity, false); + permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); Context.getManager(baseClass).updateItem(entity); LogAction.edit(getUserId(), entity); @@ -152,13 +100,8 @@ public abstract class BaseObjectResource extends BaseResour @Path("{id}") @DELETE public Response remove(@PathParam("id") long id) throws StorageException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), id); + permissionsService.checkEdit(getUserId(), baseClass, false); + permissionsService.checkPermission(baseClass, getUserId(), id); BaseObjectManager manager = Context.getManager(baseClass); manager.removeItem(id); diff --git a/src/main/java/org/traccar/api/BaseResource.java b/src/main/java/org/traccar/api/BaseResource.java index 6dff8c8c3..33abe73fa 100644 --- a/src/main/java/org/traccar/api/BaseResource.java +++ b/src/main/java/org/traccar/api/BaseResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 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. @@ -15,8 +15,11 @@ */ package org.traccar.api; +import org.traccar.api.security.PermissionsService; import org.traccar.api.security.UserPrincipal; +import org.traccar.storage.Storage; +import javax.inject.Inject; import javax.ws.rs.core.Context; import javax.ws.rs.core.SecurityContext; @@ -25,6 +28,12 @@ public class BaseResource { @Context private SecurityContext securityContext; + @Inject + protected Storage storage; + + @Inject + protected PermissionsService permissionsService; + protected long getUserId() { UserPrincipal principal = (UserPrincipal) securityContext.getUserPrincipal(); if (principal != null) { @@ -32,4 +41,5 @@ public class BaseResource { } return 0; } + } diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 9e554217e..a12314a2c 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.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"); @@ -16,17 +16,19 @@ */ package org.traccar.api; -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.GET; import javax.ws.rs.QueryParam; - -import org.traccar.Context; -import org.traccar.database.ExtendedObjectManager; -import org.traccar.model.BaseModel; +import java.util.Collection; +import java.util.LinkedList; public class ExtendedObjectResource extends BaseObjectResource { @@ -36,27 +38,28 @@ public class ExtendedObjectResource extends BaseObjectResou @GET public Collection get( - @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("groupId") long groupId, - @QueryParam("deviceId") long deviceId, @QueryParam("refresh") boolean refresh) throws SQLException { - - ExtendedObjectManager manager = (ExtendedObjectManager) Context.getManager(getBaseClass()); - if (refresh) { - manager.refreshItems(); - } + @QueryParam("all") boolean all, @QueryParam("userId") long userId, + @QueryParam("groupId") long groupId, @QueryParam("deviceId") long deviceId) throws StorageException { - Set result = new HashSet<>(getSimpleManagerItems(manager, all, userId)); + var conditions = new LinkedList(); - if (groupId != 0) { - Context.getPermissionsManager().checkGroup(getUserId(), groupId); - result.retainAll(manager.getGroupItems(groupId)); + if (all) { + permissionsService.checkAdmin(getUserId()); + } else { + permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, userId, baseClass)); } - if (deviceId != 0) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - result.retainAll(manager.getDeviceItems(deviceId)); + if (groupId > 0) { + permissionsService.checkPermission(Group.class, getUserId(), groupId); + conditions.add(new Condition.Permission(Group.class, groupId, baseClass)); + } + if (deviceId > 0) { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + conditions.add(new Condition.Permission(Device.class, deviceId, baseClass)); } - return manager.getItems(result); + return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); } } diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index 77731a810..0433147f8 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2021 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"); @@ -17,7 +17,6 @@ package org.traccar.api; import java.io.IOException; -import java.sql.SQLException; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -76,9 +75,6 @@ public class MediaFilter implements Filter { } catch (SecurityException e) { httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); httpResponse.getWriter().println(Log.exceptionStack(e)); - } catch (SQLException e) { - httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); - httpResponse.getWriter().println(Log.exceptionStack(e)); } } diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index a7fcae0e7..b55bf91e3 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.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"); @@ -16,15 +16,17 @@ */ package org.traccar.api; -import java.sql.SQLException; -import java.util.Collection; +import org.traccar.model.BaseModel; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.GET; import javax.ws.rs.QueryParam; - -import org.traccar.Context; -import org.traccar.database.BaseObjectManager; -import org.traccar.model.BaseModel; +import java.util.Collection; +import java.util.LinkedList; public class SimpleObjectResource extends BaseObjectResource { @@ -34,10 +36,18 @@ public class SimpleObjectResource extends BaseObjectResourc @GET public Collection get( - @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { + @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws StorageException { + + var conditions = new LinkedList(); + + if (all) { + permissionsService.checkAdmin(getUserId()); + } else { + permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, userId, baseClass)); + } - BaseObjectManager manager = Context.getManager(getBaseClass()); - return manager.getItems(getSimpleManagerItems(manager, all, userId)); + return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); } } diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 9436b59f6..309308e75 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -31,8 +31,6 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - -import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -51,7 +49,7 @@ public class DeviceResource extends BaseObjectResource { public Collection get( @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("uniqueId") List uniqueIds, - @QueryParam("id") List deviceIds) throws SQLException { + @QueryParam("id") List deviceIds) { DeviceManager deviceManager = Context.getDeviceManager(); Set result; if (all) { diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 354d96e4f..38b101b25 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -15,6 +15,11 @@ */ package org.traccar.api.resource; +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.model.Event; +import org.traccar.storage.StorageException; + import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -24,13 +29,6 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.model.Event; -import org.traccar.model.Geofence; -import org.traccar.model.Maintenance; -import org.traccar.storage.StorageException; - @Path("events") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -44,12 +42,6 @@ public class EventResource extends BaseResource { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } Context.getPermissionsManager().checkDevice(getUserId(), event.getDeviceId()); - if (event.getGeofenceId() != 0) { - Context.getPermissionsManager().checkPermission(Geofence.class, getUserId(), event.getGeofenceId()); - } - if (event.getMaintenanceId() != 0) { - Context.getPermissionsManager().checkPermission(Maintenance.class, getUserId(), event.getMaintenanceId()); - } return event; } diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 9631a52b7..cf4b66fa1 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 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. @@ -33,7 +33,6 @@ import org.traccar.model.Notification; import org.traccar.model.Typed; import org.traccar.notification.MessageException; - @Path("notifications") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 511032402..941417231 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -55,7 +55,7 @@ public class PositionResource extends BaseResource { } else { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); if (from != null && to != null) { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return Context.getDataManager().getPositions(deviceId, from, to); } else { return Collections.singleton(Context.getDeviceManager().getLastPosition(deviceId)); diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 03df0d03a..901385d0d 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -99,7 +99,7 @@ public class ReportResource extends BaseResource { public Collection getRoute( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -111,7 +111,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -124,7 +124,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); } @@ -137,7 +137,7 @@ public class ReportResource extends BaseResource { @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); @@ -150,7 +150,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); } @@ -163,7 +163,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); @@ -176,7 +176,7 @@ public class ReportResource extends BaseResource { public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -188,7 +188,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -201,7 +201,7 @@ public class ReportResource extends BaseResource { public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -213,7 +213,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); Stops.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java new file mode 100644 index 000000000..e39b8808f --- /dev/null +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -0,0 +1,136 @@ +/* + * 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.api.security; + +import org.traccar.model.Calendar; +import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.GroupedModel; +import org.traccar.model.ScheduledModel; +import org.traccar.model.Server; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; + +public class PermissionsService { + + private final Storage storage; + + private Server server; + private User user; + + @Inject + public PermissionsService(Storage storage) { + this.storage = storage; + } + + private Server getServer() throws StorageException { + if (server == null) { + server = storage.getObject( + Server.class, new Request(new Columns.All())); + } + return server; + } + + private User getUser(long userId) throws StorageException { + if (user == null) { + user = storage.getObject( + User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + } + return user; + } + + public void checkAdmin(long userId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + throw new SecurityException("Account is readonly"); + } + } + + public void checkReports(long userId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator() + && (server.getDisableReports() || getUser(userId).getDisableReports())) { + throw new SecurityException("Reports are disabled"); + } + } + + public void checkEdit(long userId, Class clazz, boolean addition) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + boolean denied = false; + if (getServer().getReadonly() || getUser(userId).getReadonly()) { + denied = true; + } else if (clazz.equals(Device.class)) { + denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly(); + if (addition) { + int deviceCount = storage.getPermissions(User.class, userId, Device.class).size(); + denied = deviceCount >= getUser(userId).getDeviceLimit(); + } + } else if (clazz.equals(Command.class)) { + denied = getServer().getLimitCommands() || getUser(userId).getLimitCommands(); + } + if (denied) { + throw new SecurityException("Write access denied"); + } + } + } + + public void checkEdit(long userId, Object object, boolean addition) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + checkEdit(userId, object.getClass(), addition); + boolean denied = false; + if (object instanceof GroupedModel) { + long groupId = ((GroupedModel) object).getGroupId(); + if (groupId > 0) { + denied = storage.getPermissions(User.class, userId, Group.class, groupId).isEmpty(); + // TODO TEST NESTED GROUP PERMISSION + } + } + if (object instanceof ScheduledModel) { + long calendarId = ((ScheduledModel) object).getCalendarId(); + if (calendarId > 0) { + denied = storage.getPermissions(User.class, userId, Calendar.class, calendarId).isEmpty(); + } + } + if (denied) { + throw new SecurityException("Write access denied"); + } + } + } + + public void checkUser(long userId, long managedUserId) throws StorageException, SecurityException { + if (userId != managedUserId && !getUser(userId).getAdministrator()) { + if (!getUser(userId).getManager() + || storage.getPermissions(User.class, userId, User.class, managedUserId).isEmpty()) { + throw new SecurityException("User access denied"); + } + } + } + + public void checkPermission( + Class clazz, long userId, long objectId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator() + && storage.getPermissions(User.class, userId, clazz, objectId).isEmpty()) { + // TODO handle nested objects + throw new SecurityException(clazz.getSimpleName() + " access denied"); + } + } + +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ccfe4bee7..1341f4143 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1271,6 +1271,13 @@ public final class Keys { "logger.console", Collections.singletonList(KeyType.GLOBAL)); + /** + * Log executed SQL queries. + */ + public static final ConfigKey LOGGER_QUERIES = new ConfigKey<>( + "logger.queries", + Collections.singletonList(KeyType.GLOBAL)); + /** * Log file name. For rotating logs, a date is added at the end of the file name for non-current logs. */ diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 40591e869..a9b8454eb 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,7 +15,6 @@ */ package org.traccar.database; -import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; @@ -110,7 +109,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } @Override - public Device getByUniqueId(String uniqueId) throws SQLException { + public Device getByUniqueId(String uniqueId) { boolean forceUpdate; try { readLock(); diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 2bb808033..9a673c784 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -264,45 +264,23 @@ public class PermissionsManager { return user != null && user.getReadonly(); } - public boolean getUserDeviceReadonly(long userId) { - User user = getUser(userId); - return user != null && user.getDeviceReadonly(); - } - public boolean getUserLimitCommands(long userId) { User user = getUser(userId); return user != null && user.getLimitCommands(); } - public boolean getUserDisableReport(long userId) { - User user = getUser(userId); - return user != null && user.getDisableReports(); - } - public void checkReadonly(long userId) throws SecurityException { if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { throw new SecurityException("Account is readonly"); } } - public void checkDeviceReadonly(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getDeviceReadonly() || getUserDeviceReadonly(userId))) { - throw new SecurityException("Account is device readonly"); - } - } - public void checkLimitCommands(long userId) throws SecurityException { if (!getUserAdmin(userId) && (server.getLimitCommands() || getUserLimitCommands(userId))) { throw new SecurityException("Account has limit sending commands"); } } - public void checkDisableReports(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getDisableReports() || getUserDisableReport(userId))) { - throw new SecurityException("Account has reports disabled"); - } - } - public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException { if (!getUserAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) { throw new SecurityException("Command can not be sent to this device"); diff --git a/src/main/java/org/traccar/model/Permission.java b/src/main/java/org/traccar/model/Permission.java index ad0176b39..bace6b7d4 100644 --- a/src/main/java/org/traccar/model/Permission.java +++ b/src/main/java/org/traccar/model/Permission.java @@ -71,7 +71,7 @@ public class Permission { data.put(getKey(propertyClass), propertyId); } - private static String getKey(Class clazz) { + public static String getKey(Class clazz) { return Introspector.decapitalize(clazz.getSimpleName()) + "Id"; } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 464d0cbfe..6a67f3276 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -79,6 +79,12 @@ public class User extends ExtendedModel { private boolean administrator; + @QueryIgnore + @JsonIgnore + public boolean getManager() { + return userLimit != 0; + } + public boolean getAdministrator() { return administrator; } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index d73dc7b25..4c985d98a 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -1,3 +1,18 @@ +/* + * 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.storage; import org.traccar.model.Permission; @@ -10,6 +25,7 @@ import org.traccar.storage.query.Request; import javax.sql.DataSource; import java.sql.SQLException; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -96,9 +112,20 @@ public class DatabaseStorage extends Storage { } @Override - public List getPermissions(Class ownerClass, Class propertyClass) throws StorageException { + public List getPermissions( + Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException { StringBuilder query = new StringBuilder("SELECT * FROM "); query.append(Permission.getStorageName(ownerClass, propertyClass)); + var conditions = new LinkedList(); + if (ownerId > 0) { + conditions.add(new Condition.Equals( + Permission.getKey(ownerClass), Permission.getKey(ownerClass), ownerId)); + } + if (propertyId > 0) { + conditions.add(new Condition.Equals( + Permission.getKey(propertyClass), Permission.getKey(propertyClass), propertyId)); + } + query.append(formatCondition(Condition.merge(conditions))); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); return builder.executePermissionsQuery(); @@ -154,18 +181,21 @@ public class DatabaseStorage extends Storage { private Map getConditionVariables(Condition genericCondition) { Map results = new HashMap<>(); if (genericCondition instanceof Condition.Compare) { - Condition.Compare condition = (Condition.Compare) genericCondition; + var condition = (Condition.Compare) genericCondition; if (condition.getValue() != null) { results.put(condition.getVariable(), condition.getValue()); } } else if (genericCondition instanceof Condition.Between) { - Condition.Between condition = (Condition.Between) genericCondition; + var condition = (Condition.Between) genericCondition; results.put(condition.getFromVariable(), condition.getFromValue()); results.put(condition.getToVariable(), condition.getToValue()); } else if (genericCondition instanceof Condition.Binary) { - Condition.Binary condition = (Condition.Binary) genericCondition; + var condition = (Condition.Binary) genericCondition; results.putAll(getConditionVariables(condition.getFirst())); results.putAll(getConditionVariables(condition.getSecond())); + } else if (genericCondition instanceof Condition.Permission) { + var condition = (Condition.Permission) genericCondition; + results.put(Permission.getKey(condition.getOwnerClass()), condition.getOwnerId()); } return results; } @@ -187,7 +217,7 @@ public class DatabaseStorage extends Storage { } if (genericCondition instanceof Condition.Compare) { - Condition.Compare condition = (Condition.Compare) genericCondition; + var condition = (Condition.Compare) genericCondition; result.append(condition.getColumn()); result.append(" "); result.append(condition.getOperator()); @@ -196,7 +226,7 @@ public class DatabaseStorage extends Storage { } else if (genericCondition instanceof Condition.Between) { - Condition.Between condition = (Condition.Between) genericCondition; + var condition = (Condition.Between) genericCondition; result.append(condition.getColumn()); result.append(" BETWEEN :"); result.append(condition.getFromVariable()); @@ -205,13 +235,26 @@ public class DatabaseStorage extends Storage { } else if (genericCondition instanceof Condition.Binary) { - Condition.Binary condition = (Condition.Binary) genericCondition; + var condition = (Condition.Binary) genericCondition; result.append(formatCondition(condition.getFirst(), false)); result.append(" "); result.append(condition.getOperator()); result.append(" "); result.append(formatCondition(condition.getSecond(), false)); + } else if (genericCondition instanceof Condition.Permission) { + + var condition = (Condition.Permission) genericCondition; + result.append("id IN (SELECT "); + result.append(Permission.getKey(condition.getPropertyClass())); + result.append(" FROM "); + result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); + result.append(" WHERE "); + result.append(Permission.getKey(condition.getOwnerClass())); + result.append(" = :"); + result.append(Permission.getKey(condition.getOwnerClass())); + result.append(")"); + } } return result.toString(); diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 9cfe30a2b..115bbea7a 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -38,8 +38,11 @@ public class MemoryStorage extends Storage { } @Override - public List getPermissions(Class ownerClass, Class propertyClass) { + public List getPermissions( + Class ownerClass, long ownerId, Class propertyClass, long propertyId) { return getPermissionsSet(ownerClass, propertyClass).stream() + .filter(pair -> ownerId == 0 || pair.getFirst().equals(ownerId)) + .filter(pair -> propertyId == 0 || pair.getSecond().equals(propertyId)) .map(pair -> new Permission(ownerClass, pair.getFirst(), propertyClass, pair.getSecond())) .collect(Collectors.toList()); } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index da8002f0b..874a046b4 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.config.Keys; import org.traccar.model.Permission; import javax.sql.DataSource; @@ -309,15 +310,6 @@ public final class QueryBuilder { void process(T object, ResultSet resultSet) throws SQLException; } - public T executeQuerySingle(Class clazz) throws SQLException { - List result = executeQuery(clazz); - if (!result.isEmpty()) { - return result.iterator().next(); - } else { - return null; - } - } - private void addProcessors( List> processors, final Class parameterType, final Method method, final String name) { @@ -395,6 +387,12 @@ public final class QueryBuilder { } } + private void logQuery() { + if (Context.getConfig().getBoolean(Keys.LOGGER_QUERIES)) { + LOGGER.info(query); + } + } + public List executeQuery(Class clazz) throws SQLException { List result = new LinkedList<>(); @@ -402,6 +400,8 @@ public final class QueryBuilder { try { + logQuery(); + try (ResultSet resultSet = statement.executeQuery()) { ResultSetMetaData resultMetaData = resultSet.getMetaData(); @@ -457,6 +457,7 @@ public final class QueryBuilder { if (query != null) { try { + logQuery(); statement.execute(); if (returnGeneratedKeys) { ResultSet resultSet = statement.getGeneratedKeys(); @@ -476,6 +477,7 @@ public final class QueryBuilder { List result = new LinkedList<>(); if (query != null) { try { + logQuery(); try (ResultSet resultSet = statement.executeQuery()) { ResultSetMetaData resultMetaData = resultSet.getMetaData(); while (resultSet.next()) { diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 22c48cae0..3b27f57e9 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -16,12 +16,27 @@ public abstract class Storage { public abstract void removeObject(Class clazz, Request request) throws StorageException; public abstract List getPermissions( - Class ownerClass, Class propertyClass) throws StorageException; + Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException; public abstract void addPermission(Permission permission) throws StorageException; public abstract void removePermission(Permission permission) throws StorageException; + public List getPermissions( + Class ownerClass, Class propertyClass) throws StorageException { + return getPermissions(ownerClass, 0, propertyClass, 0); + } + + public List getPermissions( + Class ownerClass, long ownerId, Class propertyClass) throws StorageException { + return getPermissions(ownerClass, ownerId, propertyClass, 0); + } + + public List getPermissions( + Class ownerClass, Class propertyClass, long propertyId) throws StorageException { + return getPermissions(ownerClass, 0, propertyClass, propertyId); + } + public T getObject(Class clazz, Request request) throws StorageException { var objects = getObjects(clazz, request); return objects.isEmpty() ? null : objects.get(0); diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 82c8e8479..304440698 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -1,7 +1,21 @@ package org.traccar.storage.query; +import java.util.List; + public interface Condition { + static Condition merge(List conditions) { + Condition result = null; + var iterator = conditions.iterator(); + if (iterator.hasNext()) { + result = iterator.next(); + while (iterator.hasNext()) { + result = new Condition.And(result, iterator.next()); + } + } + return result; + } + class Equals extends Compare { public Equals(String column, String variable) { this(column, variable, null); @@ -114,4 +128,28 @@ public interface Condition { } } + class Permission implements Condition { + private final Class ownerClass; + private final long ownerId; + private final Class propertyClass; + + public Permission(Class ownerClass, long ownerId, Class propertyClass) { + this.ownerClass = ownerClass; + this.ownerId = ownerId; + this.propertyClass = propertyClass; + } + + public Class getOwnerClass() { + return ownerClass; + } + + public long getOwnerId() { + return ownerId; + } + + public Class getPropertyClass() { + return propertyClass; + } + } + } -- cgit v1.2.3 From 8f90707e17e66e9d1aa98fa5fd06cdd30e9c2760 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Apr 2022 18:17:52 -0700 Subject: Migrate attribute resource --- .../traccar/api/resource/AttributeResource.java | 68 +++++++++++++--------- 1 file changed, 41 insertions(+), 27 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index d2dc28903..478b7acfd 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,9 +30,13 @@ import javax.ws.rs.core.Response; import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Attribute; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.handler.ComputedAttributesHandler; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; @Path("attributes/computed") @Produces(MediaType.APPLICATION_JSON) @@ -45,51 +49,61 @@ public class AttributeResource extends ExtendedObjectResource { @POST @Path("test") - public Response test(@QueryParam("deviceId") long deviceId, Attribute entity) { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - Position last = Context.getIdentityManager().getLastPosition(deviceId); - if (last != null) { - Object result = new ComputedAttributesHandler( - Context.getConfig(), - Context.getIdentityManager(), - Context.getAttributesManager()).computeAttribute(entity, last); - if (result != null) { - switch (entity.getType()) { - case "number": - Number numberValue = (Number) result; - return Response.ok(numberValue).build(); - case "boolean": - Boolean booleanValue = (Boolean) result; - return Response.ok(booleanValue).build(); - default: - return Response.ok(result.toString()).build(); - } - } else { - return Response.noContent().build(); + public Response test(@QueryParam("deviceId") long deviceId, Attribute entity) throws StorageException { + permissionsService.checkAdmin(getUserId()); + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), + new Condition.Equals("id", "id", deviceId))); + if (device == null) { + throw new IllegalArgumentException("Device not found"); + } + + Position last = storage.getObject(Position.class, new Request( + new Columns.All(), + new Condition.Equals("id", "id", device.getPositionId()))); + if (last == null) { + throw new IllegalArgumentException("Device has no last position"); + } + + Object result = new ComputedAttributesHandler( + Context.getConfig(), + Context.getIdentityManager(), + Context.getAttributesManager()).computeAttribute(entity, last); + if (result != null) { + switch (entity.getType()) { + case "number": + Number numberValue = (Number) result; + return Response.ok(numberValue).build(); + case "boolean": + Boolean booleanValue = (Boolean) result; + return Response.ok(booleanValue).build(); + default: + return Response.ok(result.toString()).build(); } } else { - throw new IllegalArgumentException("Device has no last position"); + return Response.noContent().build(); } } @POST public Response add(Attribute entity) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); + permissionsService.checkAdmin(getUserId()); return super.add(entity); } @Path("{id}") @PUT public Response update(Attribute entity) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); + permissionsService.checkAdmin(getUserId()); return super.update(entity); } @Path("{id}") @DELETE public Response remove(@PathParam("id") long id) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); + permissionsService.checkAdmin(getUserId()); return super.remove(id); } -- cgit v1.2.3 From b164114d23ad3d0f965c003489e31a6c0d78b0d3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Apr 2022 19:54:32 -0700 Subject: Fix user creation --- src/main/java/org/traccar/database/UsersManager.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java index 31759dc8b..a54226cfe 100644 --- a/src/main/java/org/traccar/database/UsersManager.java +++ b/src/main/java/org/traccar/database/UsersManager.java @@ -59,6 +59,12 @@ public class UsersManager extends SimpleObjectManager { } } + @Override + public void addItem(User user) throws StorageException { + super.addItem(user); + getDataManager().updateUserPassword(user); + } + @Override public void updateItem(User user) throws StorageException { if (user.getHashedPassword() != null) { -- cgit v1.2.3 From 517c6a5ad687bb627caa665452043dae3be52bcf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 11:10:05 -0700 Subject: Fix simple objects get --- src/main/java/org/traccar/api/SimpleObjectResource.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index b55bf91e3..c61101077 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -43,7 +43,11 @@ public class SimpleObjectResource extends BaseObjectResourc if (all) { permissionsService.checkAdmin(getUserId()); } else { - permissionsService.checkUser(getUserId(), userId); + if (userId == 0) { + userId = getUserId(); + } else { + permissionsService.checkUser(getUserId(), userId); + } conditions.add(new Condition.Permission(User.class, userId, baseClass)); } -- cgit v1.2.3 From c2c58a30ae0857c4e584b128899baa63a684a892 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 13:18:43 -0700 Subject: Fix extended object resource --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index a12314a2c..40d679ded 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -46,7 +46,11 @@ public class ExtendedObjectResource extends BaseObjectResou if (all) { permissionsService.checkAdmin(getUserId()); } else { - permissionsService.checkUser(getUserId(), userId); + if (userId == 0) { + userId = getUserId(); + } else { + permissionsService.checkUser(getUserId(), userId); + } conditions.add(new Condition.Permission(User.class, userId, baseClass)); } -- cgit v1.2.3 From dd8fa719d7726489e76944029d2aed214ba8a904 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 15:37:33 -0700 Subject: Handle group permissions --- .../java/org/traccar/storage/DatabaseStorage.java | 112 ++++++++++++++++++--- .../java/org/traccar/storage/query/Condition.java | 46 ++++++++- 2 files changed, 141 insertions(+), 17 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 4c985d98a..ff77ff8a8 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -15,6 +15,9 @@ */ package org.traccar.storage; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.GroupedModel; import org.traccar.model.Permission; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; @@ -43,7 +46,7 @@ public class DatabaseStorage extends Storage { public List getObjects(Class clazz, Request request) throws StorageException { StringBuilder query = new StringBuilder("SELECT "); query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); - query.append(" FROM ").append(getTableName(clazz)); + query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); query.append(formatLimit(request.getLimit())); @@ -61,7 +64,7 @@ public class DatabaseStorage extends Storage { @Override public long addObject(T entity, Request request) throws StorageException { StringBuilder query = new StringBuilder("INSERT INTO "); - query.append(getTableName(entity.getClass())); + query.append(getStorageName(entity.getClass())); query.append("("); query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c)); query.append(") VALUES ("); @@ -79,7 +82,7 @@ public class DatabaseStorage extends Storage { @Override public void updateObject(T entity, Request request) throws StorageException { StringBuilder query = new StringBuilder("UPDATE "); - query.append(getTableName(entity.getClass())); + query.append(getStorageName(entity.getClass())); query.append(" SET "); query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); @@ -98,7 +101,7 @@ public class DatabaseStorage extends Storage { @Override public void removeObject(Class clazz, Request request) throws StorageException { StringBuilder query = new StringBuilder("DELETE FROM "); - query.append(getTableName(clazz)); + query.append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); @@ -170,7 +173,7 @@ public class DatabaseStorage extends Storage { } } - private String getTableName(Class clazz) throws StorageException { + private String getStorageName(Class clazz) throws StorageException { StorageName storageName = clazz.getAnnotation(StorageName.class); if (storageName == null) { throw new StorageException("StorageName annotation is missing"); @@ -195,7 +198,11 @@ public class DatabaseStorage extends Storage { results.putAll(getConditionVariables(condition.getSecond())); } else if (genericCondition instanceof Condition.Permission) { var condition = (Condition.Permission) genericCondition; - results.put(Permission.getKey(condition.getOwnerClass()), condition.getOwnerId()); + if (condition.getOwnerId() > 0) { + results.put(Permission.getKey(condition.getOwnerClass()), condition.getOwnerId()); + } else { + results.put(Permission.getKey(condition.getPropertyClass()), condition.getPropertyId()); + } } return results; } @@ -205,11 +212,11 @@ public class DatabaseStorage extends Storage { return columns.getColumns(clazz, type).stream().map(mapper).collect(Collectors.joining(", ")); } - private String formatCondition(Condition genericCondition) { + private String formatCondition(Condition genericCondition) throws StorageException { return formatCondition(genericCondition, true); } - private String formatCondition(Condition genericCondition, boolean appendWhere) { + private String formatCondition(Condition genericCondition, boolean appendWhere) throws StorageException { StringBuilder result = new StringBuilder(); if (genericCondition != null) { if (appendWhere) { @@ -245,14 +252,8 @@ public class DatabaseStorage extends Storage { } else if (genericCondition instanceof Condition.Permission) { var condition = (Condition.Permission) genericCondition; - result.append("id IN (SELECT "); - result.append(Permission.getKey(condition.getPropertyClass())); - result.append(" FROM "); - result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); - result.append(" WHERE "); - result.append(Permission.getKey(condition.getOwnerClass())); - result.append(" = :"); - result.append(Permission.getKey(condition.getOwnerClass())); + result.append("id IN ("); + result.append(formatPermissionQuery(condition)); result.append(")"); } @@ -281,4 +282,83 @@ public class DatabaseStorage extends Storage { return result.toString(); } + private String formatPermissionQuery(Condition.Permission condition) throws StorageException { + StringBuilder result = new StringBuilder(); + + String outputKey; + String conditionKey; + if (condition.getOwnerId() > 0) { + outputKey = Permission.getKey(condition.getPropertyClass()); + conditionKey = Permission.getKey(condition.getOwnerClass()); + } else { + outputKey = Permission.getKey(condition.getOwnerClass()); + conditionKey = Permission.getKey(condition.getPropertyClass()); + } + + result.append("SELECT "); + result.append(outputKey); + result.append(" FROM "); + result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); + result.append(" WHERE "); + result.append(conditionKey); + result.append(" = :"); + result.append(conditionKey); + + if (condition.getIncludeGroups()) { + + boolean expandDevices; + String groupStorageName; + if (GroupedModel.class.isAssignableFrom(condition.getOwnerClass())) { + expandDevices = Device.class.isAssignableFrom(condition.getOwnerClass()); + groupStorageName = Permission.getStorageName(Group.class, condition.getPropertyClass()); + } else { + expandDevices = Device.class.isAssignableFrom(condition.getPropertyClass()); + groupStorageName = Permission.getStorageName(condition.getOwnerClass(), Group.class); + } + + result.append(" UNION "); + + result.append("SELECT DISTINCT "); + result.append(expandDevices? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) + result.append(outputKey); + result.append(" FROM "); + result.append(groupStorageName); + + result.append(" INNER JOIN ("); + result.append("SELECT id as parentid, id as groupid FROM "); + result.append(getStorageName(Group.class)); + result.append(" UNION "); + result.append("SELECT groupid as parentid, id as groupid FROM "); + result.append(getStorageName(Group.class)); + result.append(" WHERE groupid IS NOT NULL"); + result.append(" UNION "); + result.append("SELECT g2.groupid as parentid, g1.id as groupid FROM "); + result.append(getStorageName(Group.class)); + result.append(" AS g2"); + result.append(" INNER JOIN "); + result.append(getStorageName(Group.class)); + result.append(" AS g1 ON g2.id = g1.groupid"); + result.append(" WHERE g2.groupid IS NOT NULL"); + result.append(") AS groups ON "); + result.append(groupStorageName); + result.append(".groupid = groups.parentid"); + + if (expandDevices) { + result.append(" INNER JOIN ("); + result.append("SELECT groupid as parentid, id as deviceid FROM "); + result.append(getStorageName(Device.class)); + result.append(" WHERE groupid IS NOT NULL"); + result.append(") AS devices ON groups.groupid = devices.parentid"); + } + + result.append(" WHERE "); + result.append(conditionKey); // TODO handle search for device / group + result.append(" = :"); + result.append(conditionKey); + + } + + return result.toString(); + } + } diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 304440698..91ede236c 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -1,5 +1,22 @@ +/* + * 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.storage.query; +import org.traccar.model.GroupedModel; + import java.util.List; public interface Condition { @@ -132,11 +149,28 @@ public interface Condition { private final Class ownerClass; private final long ownerId; private final Class propertyClass; + private final long propertyId; + private final boolean excludeGroups; - public Permission(Class ownerClass, long ownerId, Class propertyClass) { + private Permission( + Class ownerClass, long ownerId, Class propertyClass, long propertyId, boolean excludeGroups) { this.ownerClass = ownerClass; this.ownerId = ownerId; this.propertyClass = propertyClass; + this.propertyId = propertyId; + this.excludeGroups = excludeGroups; + } + + public Permission(Class ownerClass, long ownerId, Class propertyClass) { + this(ownerClass, ownerId, propertyClass, 0, false); + } + + public Permission(Class ownerClass, Class propertyClass, long propertyId) { + this(ownerClass, 0, propertyClass, propertyId, false); + } + + public Permission excludeGroups() { + return new Permission(this.ownerClass, this.ownerId, this.propertyClass, this.propertyId, true); } public Class getOwnerClass() { @@ -150,6 +184,16 @@ public interface Condition { public Class getPropertyClass() { return propertyClass; } + + public long getPropertyId() { + return propertyId; + } + + public boolean getIncludeGroups() { + boolean ownerGroupModel = GroupedModel.class.isAssignableFrom(ownerClass); + boolean propertyGroupModel = GroupedModel.class.isAssignableFrom(propertyClass); + return (ownerGroupModel || propertyGroupModel) && !excludeGroups; + } } } -- cgit v1.2.3 From 5fe089626bd367241d3424a0b71dee87805673ca Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 19:51:37 -0700 Subject: Fix nested permission check --- .../traccar/api/security/PermissionsService.java | 26 +++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index e39b8808f..c640f8d74 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; import org.traccar.model.Device; @@ -99,8 +100,7 @@ public class PermissionsService { if (object instanceof GroupedModel) { long groupId = ((GroupedModel) object).getGroupId(); if (groupId > 0) { - denied = storage.getPermissions(User.class, userId, Group.class, groupId).isEmpty(); - // TODO TEST NESTED GROUP PERMISSION + checkPermission(Group.class, userId, groupId); } } if (object instanceof ScheduledModel) { @@ -124,12 +124,22 @@ public class PermissionsService { } } - public void checkPermission( - Class clazz, long userId, long objectId) throws StorageException, SecurityException { - if (!getUser(userId).getAdministrator() - && storage.getPermissions(User.class, userId, clazz, objectId).isEmpty()) { - // TODO handle nested objects - throw new SecurityException(clazz.getSimpleName() + " access denied"); + public void checkPermission( + Class clazz, long userId, long objectId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + var objects = storage.getObjects(clazz, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, userId, clazz))); + boolean found = false; + for (var object : objects) { + if (object.getId() == objectId) { + found = true; + break; + } + } + if (!found) { + throw new SecurityException(clazz.getSimpleName() + " access denied"); + } } } -- cgit v1.2.3 From 9c9f5d66147cfa428ea18dd29103b9c82e529dca Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 19:53:09 -0700 Subject: Add license notices --- src/main/java/org/traccar/storage/MemoryStorage.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/Storage.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/StorageException.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/StorageName.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Columns.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Limit.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Order.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Request.java | 15 +++++++++++++++ 8 files changed, 120 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 115bbea7a..71e895428 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -1,3 +1,18 @@ +/* + * 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.storage; import org.traccar.model.Pair; diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 3b27f57e9..22b5aaedc 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -1,3 +1,18 @@ +/* + * 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.storage; import org.traccar.model.Permission; diff --git a/src/main/java/org/traccar/storage/StorageException.java b/src/main/java/org/traccar/storage/StorageException.java index 6c1e9c2ff..3f066cae6 100644 --- a/src/main/java/org/traccar/storage/StorageException.java +++ b/src/main/java/org/traccar/storage/StorageException.java @@ -1,3 +1,18 @@ +/* + * 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.storage; public class StorageException extends Exception { diff --git a/src/main/java/org/traccar/storage/StorageName.java b/src/main/java/org/traccar/storage/StorageName.java index b6fa55e02..bf824c333 100644 --- a/src/main/java/org/traccar/storage/StorageName.java +++ b/src/main/java/org/traccar/storage/StorageName.java @@ -1,3 +1,18 @@ +/* + * 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.storage; import java.lang.annotation.ElementType; diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 196d2281c..97ca13be9 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -1,3 +1,18 @@ +/* + * 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.storage.query; import org.traccar.storage.QueryExtended; diff --git a/src/main/java/org/traccar/storage/query/Limit.java b/src/main/java/org/traccar/storage/query/Limit.java index 4a20f0ce2..9673e5426 100644 --- a/src/main/java/org/traccar/storage/query/Limit.java +++ b/src/main/java/org/traccar/storage/query/Limit.java @@ -1,3 +1,18 @@ +/* + * 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.storage.query; public class Limit { diff --git a/src/main/java/org/traccar/storage/query/Order.java b/src/main/java/org/traccar/storage/query/Order.java index 6852c5ba8..d12acc83b 100644 --- a/src/main/java/org/traccar/storage/query/Order.java +++ b/src/main/java/org/traccar/storage/query/Order.java @@ -1,3 +1,18 @@ +/* + * 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.storage.query; public class Order { diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java index a98dd48f7..41aa37bf1 100644 --- a/src/main/java/org/traccar/storage/query/Request.java +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -1,3 +1,18 @@ +/* + * 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.storage.query; public class Request { -- cgit v1.2.3 From fe50b376ee5bee1a738aef3baca97e56f75633a4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Apr 2022 16:58:46 -0700 Subject: Clean up alarm commands --- src/main/java/org/traccar/model/Command.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 03961c7b2..49486bdbc 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -58,11 +58,10 @@ public class Command extends Message implements Cloneable { public static final String TYPE_GET_MODEM_STATUS = "getModemStatus"; public static final String TYPE_GET_DEVICE_STATUS = "getDeviceStatus"; public static final String TYPE_SET_SPEED_LIMIT = "setSpeedLimit"; - public static final String TYPE_MODE_POWER_SAVING = "modePowerSaving"; public static final String TYPE_MODE_DEEP_SLEEP = "modeDeepSleep"; - public static final String TYPE_ALARM_GEOFENCE = "movementAlarm"; + public static final String TYPE_ALARM_GEOFENCE = "alarmGeofence"; public static final String TYPE_ALARM_BATTERY = "alarmBattery"; public static final String TYPE_ALARM_SOS = "alarmSos"; public static final String TYPE_ALARM_REMOVE = "alarmRemove"; -- cgit v1.2.3 From ffc1b33d5d15068294aecc64dbeae20dd77d972d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 17:36:51 -0700 Subject: Huabao speeding alarm --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 5 ++++- src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 0ae08af37..b0ad9a229 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 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. @@ -122,6 +122,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { || BitUtil.check(value, 10) || BitUtil.check(value, 11)) { return Position.ALARM_FAULT; } + if (BitUtil.check(value, 7)) { + return Position.ALARM_LOW_BATTERY; + } if (BitUtil.check(value, 8)) { return Position.ALARM_POWER_OFF; } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 7aaec33e7..8ba6fcaf1 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); + verifyAttribute(decoder, binary( + "7E020000480123456789010013000000800000000301597BC506CBFF6600EB00000155210726203531010400000000EB24000C00B28986047701207027150200060089FFFFEFFF0004002D0E10000600C5FFFFFFEF697E"), + Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + verifyAttribute(decoder, binary( "7e0200008e01917159043700b300000000800000030158990606ca0fd7000400000000211129111705010400000000cc14383938363037423831303230393031363239363830010d8001aa81021388820200858301148401aa8502189b8601338702007e8801338901148a0200998b1131323334353637383941424344454647488c04000200a88d0200828e0114a00b50353338662c5530323966037e"), Position.KEY_DTCS, "P538f U029f"); -- cgit v1.2.3 From 82ab794c56d98a1aae8ea261ee709fecac9fbc54 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 17:46:00 -0700 Subject: Rename variable --- src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 83ca74ce5..75f2b0e89 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 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. @@ -54,11 +54,11 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { List positions = new LinkedList<>(); for (int i = 0; i < result.size(); i++) { JsonObject message = result.getJsonObject(i); - JsonString ident = message.getJsonString("ident"); - if (ident == null) { + JsonString identifier = message.getJsonString("ident"); + if (identifier == null) { continue; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ident.getString()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, identifier.getString()); if (deviceSession == null) { continue; } -- cgit v1.2.3 From 8d41fb57d1c753433654569d828345592f2fab10 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 17:50:10 -0700 Subject: Flespi add driver behavior --- src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 75f2b0e89..281a8a84f 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -228,6 +228,15 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_BONNET); } return true; + case "custom.wln_accel_max": + position.set("maxAcceleration", ((JsonNumber) value).doubleValue()); + return true; + case "custom.wln_brk_max": + position.set("maxBraking", ((JsonNumber) value).doubleValue()); + return true; + case "custom.wln_crn_max": + position.set("maxCornering", ((JsonNumber) value).doubleValue()); + return true; default: return false; } -- cgit v1.2.3 From a0fbcdafceafd2f00c521627a03bd108bc6f01e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 18:50:39 -0700 Subject: Add documentation references --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index feacc1ae8..7436ff9fd 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -75,15 +75,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; public static final int MSG_GPS_PHONE = 0x1A; - public static final int MSG_GPS_LBS_EXTEND = 0x1E; - public static final int MSG_HEARTBEAT = 0x23; - public static final int MSG_ADDRESS_REQUEST = 0x2A; - public static final int MSG_ADDRESS_RESPONSE = 0x97; - public static final int MSG_GPS_LBS_5 = 0x31; - public static final int MSG_GPS_LBS_STATUS_4 = 0x32; - public static final int MSG_WIFI_5 = 0x33; - public static final int MSG_AZ735_GPS = 0x32; // only extended - public static final int MSG_AZ735_ALARM = 0x33; // only extended + public static final int MSG_GPS_LBS_EXTEND = 0x1E; // JI09 + public static final int MSG_HEARTBEAT = 0x23; // GK310 + public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 + public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 + public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 + public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 + public static final int MSG_WIFI_5 = 0x33; // AZ735 + public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended + public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended public static final int MSG_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; @@ -93,25 +93,25 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_COMMAND_0 = 0x80; public static final int MSG_COMMAND_1 = 0x81; public static final int MSG_COMMAND_2 = 0x82; - public static final int MSG_TIME_REQUEST = 0x8A; + public static final int MSG_TIME_REQUEST = 0x8A; // GK310 public static final int MSG_INFO = 0x94; public static final int MSG_SERIAL = 0x9B; public static final int MSG_STRING_INFO = 0x21; - public static final int MSG_GPS_2 = 0xA0; - public static final int MSG_LBS_2 = 0xA1; - public static final int MSG_WIFI_3 = 0xA2; - public static final int MSG_FENCE_SINGLE = 0xA3; - public static final int MSG_FENCE_MULTI = 0xA4; - public static final int MSG_LBS_ALARM = 0xA5; - public static final int MSG_LBS_ADDRESS = 0xA7; - public static final int MSG_OBD = 0x8C; - public static final int MSG_DTC = 0x65; - public static final int MSG_PID = 0x66; - public static final int MSG_BMS = 0x20; - public static final int MSG_MULTIMEDIA = 0x21; - public static final int MSG_BMS_2 = 0x40; - public static final int MSG_MULTIMEDIA_2 = 0x41; - public static final int MSG_ALARM = 0x95; + public static final int MSG_GPS_2 = 0xA0; // GK310 + public static final int MSG_LBS_2 = 0xA1; // GK310 + public static final int MSG_WIFI_3 = 0xA2; // GK310 + public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 + public static final int MSG_FENCE_MULTI = 0xA4; // GK310 + public static final int MSG_LBS_ALARM = 0xA5; // GK310 + public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 + public static final int MSG_OBD = 0x8C; // FM08ABC + public static final int MSG_DTC = 0x65; // FM08ABC + public static final int MSG_PID = 0x66; // FM08ABC + public static final int MSG_BMS = 0x20; // WD-209 + public static final int MSG_MULTIMEDIA = 0x21; // WD-209 + public static final int MSG_BMS_2 = 0x40; // WD-209 + public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 + public static final int MSG_ALARM = 0x95; // JC100 private enum Variant { VXT01, -- cgit v1.2.3 From 1b601f506027c9f373de68ffca7f1f7a1dec815a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 19:39:07 -0700 Subject: Align for readability --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 7436ff9fd..6be0c73ca 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -75,15 +75,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; public static final int MSG_GPS_PHONE = 0x1A; - public static final int MSG_GPS_LBS_EXTEND = 0x1E; // JI09 - public static final int MSG_HEARTBEAT = 0x23; // GK310 - public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 - public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 - public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 - public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 - public static final int MSG_WIFI_5 = 0x33; // AZ735 - public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended - public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended + public static final int MSG_GPS_LBS_EXTEND = 0x1E; // JI09 + public static final int MSG_HEARTBEAT = 0x23; // GK310 + public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 + public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 + public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 + public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 + public static final int MSG_WIFI_5 = 0x33; // AZ735 + public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended + public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended public static final int MSG_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; @@ -93,25 +93,25 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_COMMAND_0 = 0x80; public static final int MSG_COMMAND_1 = 0x81; public static final int MSG_COMMAND_2 = 0x82; - public static final int MSG_TIME_REQUEST = 0x8A; // GK310 + public static final int MSG_TIME_REQUEST = 0x8A; // GK310 public static final int MSG_INFO = 0x94; public static final int MSG_SERIAL = 0x9B; public static final int MSG_STRING_INFO = 0x21; - public static final int MSG_GPS_2 = 0xA0; // GK310 - public static final int MSG_LBS_2 = 0xA1; // GK310 - public static final int MSG_WIFI_3 = 0xA2; // GK310 - public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 - public static final int MSG_FENCE_MULTI = 0xA4; // GK310 - public static final int MSG_LBS_ALARM = 0xA5; // GK310 - public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 - public static final int MSG_OBD = 0x8C; // FM08ABC - public static final int MSG_DTC = 0x65; // FM08ABC - public static final int MSG_PID = 0x66; // FM08ABC - public static final int MSG_BMS = 0x20; // WD-209 - public static final int MSG_MULTIMEDIA = 0x21; // WD-209 - public static final int MSG_BMS_2 = 0x40; // WD-209 - public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 - public static final int MSG_ALARM = 0x95; // JC100 + public static final int MSG_GPS_2 = 0xA0; // GK310 + public static final int MSG_LBS_2 = 0xA1; // GK310 + public static final int MSG_WIFI_3 = 0xA2; // GK310 + public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 + public static final int MSG_FENCE_MULTI = 0xA4; // GK310 + public static final int MSG_LBS_ALARM = 0xA5; // GK310 + public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 + public static final int MSG_OBD = 0x8C; // FM08ABC + public static final int MSG_DTC = 0x65; // FM08ABC + public static final int MSG_PID = 0x66; // FM08ABC + public static final int MSG_BMS = 0x20; // WD-209 + public static final int MSG_MULTIMEDIA = 0x21; // WD-209 + public static final int MSG_BMS_2 = 0x40; // WD-209 + public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 + public static final int MSG_ALARM = 0x95; // JC100 private enum Variant { VXT01, -- cgit v1.2.3 From 91612195f286a538fb81291cb5604b329c015d64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 22 Apr 2022 18:03:19 -0700 Subject: Support Meitrack extension parameters --- .../org/traccar/protocol/MeitrackProtocolDecoder.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index a9cc1de3a..013e297c0 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -404,7 +404,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x01: position.set(Position.KEY_EVENT, buf.readUnsignedByte()); @@ -430,6 +431,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x9D: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); break; + case 0xFE69: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; default: buf.readUnsignedByte(); break; @@ -438,7 +442,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x08: position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); @@ -491,7 +496,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x02: position.setLatitude(buf.readIntLE() * 0.000001); @@ -523,7 +529,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - buf.readUnsignedByte(); // id + if (buf.getUnsignedByte(buf.readerIndex()) == 0xFE) { + buf.readUnsignedShort(); // extension id + } else { + buf.readUnsignedByte(); // id + } buf.skipBytes(buf.readUnsignedByte()); // value } -- cgit v1.2.3 From bf34c777de7b8b2d87f173bda03833989b848ecf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Apr 2022 11:00:42 -0700 Subject: Flatten GT06 decoding methods --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 716 ++++++++++----------- 1 file changed, 326 insertions(+), 390 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 6be0c73ca..325527f06 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -120,6 +120,32 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private Variant variant; + private static final Pattern PATTERN_FUEL = new PatternBuilder() + .text("!AIOIL,") + .number("d+,") // device address + .number("d+.d+,") // output value + .number("(d+.d+),") // temperature + .expression("[^,]+,") // version + .number("dd") // back wave + .number("d") // software status code + .number("d,") // hardware status code + .number("(d+.d+),") // measured value + .expression("[01],") // movement status + .number("d+,") // excited wave times + .number("xx") // checksum + .compile(); + + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .text("Current position!") + .number("Lat:([NS])(d+.d+),") // latitude + .number("Lon:([EW])(d+.d+),") // longitude + .text("Course:").number("(d+.d+),") // course + .text("Speed:").number("(d+.d+),") // speed + .text("DateTime:") + .number("(dddd)-(dd)-(dd) +") // date + .number("(dd):(dd):(dd)") // time + .compile(); + private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); } @@ -318,7 +344,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeStatus(Position position, ByteBuf buf, boolean batteryLevel) { + private void decodeStatus(Position position, ByteBuf buf, boolean batteryLevel) { int status = buf.readUnsignedByte(); @@ -360,8 +386,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); } position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - return true; } private String decodeAlarm(short value) { @@ -404,72 +428,20 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - private static final Pattern PATTERN_FUEL = new PatternBuilder() - .text("!AIOIL,") - .number("d+,") // device address - .number("d+.d+,") // output value - .number("(d+.d+),") // temperature - .expression("[^,]+,") // version - .number("dd") // back wave - .number("d") // software status code - .number("d,") // hardware status code - .number("(d+.d+),") // measured value - .expression("[01],") // movement status - .number("d+,") // excited wave times - .number("xx") // checksum - .compile(); - - private Position decodeFuelData(Position position, String sentence) { - Parser parser = new Parser(PATTERN_FUEL, sentence); - if (!parser.matches()) { - return null; - } - - position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); - position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); - - return position; - } - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .text("Current position!") - .number("Lat:([NS])(d+.d+),") // latitude - .number("Lon:([EW])(d+.d+),") // longitude - .text("Course:").number("(d+.d+),") // course - .text("Speed:").number("(d+.d+),") // speed - .text("DateTime:") - .number("(dddd)-(dd)-(dd) +") // date - .number("(dd):(dd):(dd)") // time - .compile(); - - private Position decodeLocationString(Position position, String sentence) { - Parser parser = new Parser(PATTERN_LOCATION, sentence); - if (!parser.matches()) { - return null; - } - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setCourse(parser.nextDouble()); - position.setSpeed(parser.nextDouble()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); - - return position; - } - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = buf.readUnsignedByte(); int dataLength = length - 5; int type = buf.readUnsignedByte(); + Position position = new Position(getProtocolName()); DeviceSession deviceSession = null; if (type != MSG_LOGIN) { deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } + position.setDeviceId(deviceSession.getDeviceId()); if (deviceSession.getTimeZone() == null) { deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); } @@ -507,10 +479,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); } - } else if (type == MSG_HEARTBEAT) { + return null; - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + } else if (type == MSG_HEARTBEAT) { getLastLocation(position, null); @@ -539,6 +510,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { content.writeBytes(response.getBytes(StandardCharsets.US_ASCII)); sendResponse(channel, true, MSG_ADDRESS_RESPONSE, 0, content); + return null; + } else if (type == MSG_TIME_REQUEST) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); @@ -551,40 +524,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { content.writeByte(calendar.get(Calendar.SECOND)); sendResponse(channel, false, MSG_TIME_REQUEST, 0, content); - } else if (type == MSG_X1_GPS || type == MSG_X1_PHOTO_INFO) { - - return decodeX1(channel, buf, deviceSession, type); - - } else if (type == MSG_WIFI || type == MSG_WIFI_2 || type == MSG_WIFI_4) { - - return decodeWifi(channel, buf, deviceSession, type); - - } else if (type == MSG_INFO) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_POWER, buf.readShort() * 0.01); - - return position; - - } else { - - return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - - } - - return null; - } - - private Object decodeX1(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { - - if (type == MSG_X1_GPS) { + return null; - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + } else if (type == MSG_X1_GPS) { buf.readUnsignedInt(); // data and alarm @@ -632,84 +574,79 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { photos.put(pictureId, photo); sendPhotoRequest(channel, pictureId); - } - - return null; - } + return null; - private Object decodeWifi(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { + } else if (type == MSG_WIFI || type == MSG_WIFI_2 || type == MSG_WIFI_4) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + ByteBuf time = buf.readSlice(6); + DateBuilder dateBuilder = new DateBuilder() + .setYear(BcdUtil.readInteger(time, 2)) + .setMonth(BcdUtil.readInteger(time, 2)) + .setDay(BcdUtil.readInteger(time, 2)) + .setHour(BcdUtil.readInteger(time, 2)) + .setMinute(BcdUtil.readInteger(time, 2)) + .setSecond(BcdUtil.readInteger(time, 2)); + getLastLocation(position, dateBuilder.getDate()); - ByteBuf time = buf.readSlice(6); - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(time, 2)) - .setMonth(BcdUtil.readInteger(time, 2)) - .setDay(BcdUtil.readInteger(time, 2)) - .setHour(BcdUtil.readInteger(time, 2)) - .setMinute(BcdUtil.readInteger(time, 2)) - .setSecond(BcdUtil.readInteger(time, 2)); - getLastLocation(position, dateBuilder.getDate()); - - Network network = new Network(); - - int wifiCount; - if (type == MSG_WIFI_4) { - wifiCount = buf.readUnsignedByte(); - } else { - wifiCount = buf.getUnsignedByte(2); - } + Network network = new Network(); - for (int i = 0; i < wifiCount; i++) { + int wifiCount; if (type == MSG_WIFI_4) { - buf.skipBytes(2); + wifiCount = buf.readUnsignedByte(); + } else { + wifiCount = buf.getUnsignedByte(2); } - WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); - wifiAccessPoint.setMacAddress(String.format("%02x:%02x:%02x:%02x:%02x:%02x", - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())); - if (type != MSG_WIFI_4) { - wifiAccessPoint.setSignalStrength((int) buf.readUnsignedByte()); + + for (int i = 0; i < wifiCount; i++) { + if (type == MSG_WIFI_4) { + buf.skipBytes(2); + } + WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); + wifiAccessPoint.setMacAddress(String.format("%02x:%02x:%02x:%02x:%02x:%02x", + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())); + if (type != MSG_WIFI_4) { + wifiAccessPoint.setSignalStrength((int) buf.readUnsignedByte()); + } + network.addWifiAccessPoint(wifiAccessPoint); } - network.addWifiAccessPoint(wifiAccessPoint); - } - if (type != MSG_WIFI_4) { + if (type != MSG_WIFI_4) { - int cellCount = buf.readUnsignedByte(); - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); - for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); - } + int cellCount = buf.readUnsignedByte(); + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + for (int i = 0; i < cellCount; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); + } + + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeShort(0x7878); + response.writeByte(0); + response.writeByte(type); + response.writeBytes(time.resetReaderIndex()); + response.writeByte('\r'); + response.writeByte('\n'); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(0x7878); - response.writeByte(0); - response.writeByte(type); - response.writeBytes(time.resetReaderIndex()); - response.writeByte('\r'); - response.writeByte('\n'); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } - } + position.setNetwork(network); - position.setNetwork(network); + return position; - return position; - } + } else if (type == MSG_INFO) { - private Object decodeBasicOther( - Channel channel, ByteBuf buf, DeviceSession deviceSession, int type, int dataLength) { + getLastLocation(position, null); - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_POWER, buf.readShort() * 0.01); - if (type == MSG_LBS_STATUS && dataLength >= 18) { + return position; + + } else if (type == MSG_LBS_STATUS && dataLength >= 18) { return null; // space10x multi-lbs message @@ -809,15 +746,117 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_STATUS && buf.readableBytes() == 22) { + + getLastLocation(position, null); + + buf.readUnsignedByte(); // information content + buf.readUnsignedShort(); // satellites + buf.readUnsignedByte(); // alarm + buf.readUnsignedByte(); // language + + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // working mode + buf.readUnsignedShort(); // working voltage + buf.readUnsignedByte(); // reserved + buf.readUnsignedShort(); // working times + buf.readUnsignedShort(); // working time + + int value = buf.readUnsignedShort(); + double temperature = BitUtil.to(value, 15) * 0.1; + position.set(Position.PREFIX_TEMP + 1, BitUtil.check(value, 15) ? temperature : -temperature); + } else if (isSupported(type)) { - if (type == MSG_STATUS && buf.readableBytes() == 22) { - decodeHeartbeat(buf, position); + if (hasGps(type)) { + decodeGps(position, buf, false, deviceSession.getTimeZone()); } else { - decodeBasicUniversal(buf, deviceSession, type, position); + getLastLocation(position, null); + } + + if (hasLbs(type)) { + decodeLbs(position, buf, type, hasStatus(type)); + } + + if (hasStatus(type)) { + decodeStatus(position, buf, true); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + } + + if (type == MSG_GPS_LBS_1) { + if (buf.readableBytes() > 75 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); + buf.readUnsignedByte(); // alarm + buf.readUnsignedByte(); // swiped + position.set("driverLicense", data.trim()); + } else if (buf.readableBytes() == 8) { + int mask = buf.readUnsignedShort(); + position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); + if (BitUtil.check(mask, 8 + 4)) { + int value = BitUtil.to(mask, 8 + 1); + if (BitUtil.check(mask, 8 + 1)) { + value = -value; + } + position.set(Position.PREFIX_TEMP + 1, value); + } else { + int value = BitUtil.to(mask, 8 + 2); + if (BitUtil.check(mask, 8 + 5)) { + position.set(Position.PREFIX_ADC + 1, value); + } else { + position.set(Position.PREFIX_ADC + 1, value * 0.1); + } + } + } else if (buf.readableBytes() == 11) { + decodeStatus(position, buf, false); + buf.readUnsignedByte(); // alarm extension + } else if (buf.readableBytes() == 18) { + decodeStatus(position, buf, false); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + position.set("oil", buf.readUnsignedShort()); + int temperature = buf.readUnsignedByte(); + if (BitUtil.check(temperature, 7)) { + temperature = -BitUtil.to(temperature, 7); + } + position.set(Position.PREFIX_TEMP + 1, temperature); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); + } + } + + if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4) + && buf.readableBytes() >= 3 + 6) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + } + + if (type == MSG_GPS_LBS_3) { + int module = buf.readUnsignedShort(); + int subLength = buf.readUnsignedByte(); + switch (module) { + case 0x0027: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + break; + case 0x002E: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + break; + case 0x003B: + position.setAccuracy(buf.readUnsignedShort() * 0.01); + break; + default: + buf.skipBytes(subLength); + break; + } + } + + if (buf.readableBytes() == 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); } } else if (type == MSG_ALARM) { + boolean extendedAlarm = dataLength > 7; if (extendedAlarm) { decodeGps(position, buf, false, false, false, deviceSession.getTimeZone()); @@ -854,6 +893,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); break; } + } else { if (dataLength > 0) { @@ -879,117 +919,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private void decodeHeartbeat(ByteBuf buf, Position position) { - - getLastLocation(position, null); - - buf.readUnsignedByte(); // information content - buf.readUnsignedShort(); // satellites - buf.readUnsignedByte(); // alarm - buf.readUnsignedByte(); // language - - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - - buf.readUnsignedByte(); // working mode - buf.readUnsignedShort(); // working voltage - buf.readUnsignedByte(); // reserved - buf.readUnsignedShort(); // working times - buf.readUnsignedShort(); // working time - - int value = buf.readUnsignedShort(); - double temperature = BitUtil.to(value, 15) * 0.1; - position.set(Position.PREFIX_TEMP + 1, BitUtil.check(value, 15) ? temperature : -temperature); - - } - - private void decodeBasicUniversal(ByteBuf buf, DeviceSession deviceSession, int type, Position position) { - - if (hasGps(type)) { - decodeGps(position, buf, false, deviceSession.getTimeZone()); - } else { - getLastLocation(position, null); - } - - if (hasLbs(type)) { - decodeLbs(position, buf, type, hasStatus(type)); - } - - if (hasStatus(type)) { - decodeStatus(position, buf, true); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - } - - if (type == MSG_GPS_LBS_1) { - if (buf.readableBytes() > 75 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); - buf.readUnsignedByte(); // alarm - buf.readUnsignedByte(); // swiped - position.set("driverLicense", data.trim()); - } else if (buf.readableBytes() == 8) { - int mask = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); - if (BitUtil.check(mask, 8 + 4)) { - int value = BitUtil.to(mask, 8 + 1); - if (BitUtil.check(mask, 8 + 1)) { - value = -value; - } - position.set(Position.PREFIX_TEMP + 1, value); - } else { - int value = BitUtil.to(mask, 8 + 2); - if (BitUtil.check(mask, 8 + 5)) { - position.set(Position.PREFIX_ADC + 1, value); - } else { - position.set(Position.PREFIX_ADC + 1, value * 0.1); - } - } - } else if (buf.readableBytes() == 11) { - decodeStatus(position, buf, false); - buf.readUnsignedByte(); // alarm extension - } else if (buf.readableBytes() == 18) { - decodeStatus(position, buf, false); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - position.set("oil", buf.readUnsignedShort()); - int temperature = buf.readUnsignedByte(); - if (BitUtil.check(temperature, 7)) { - temperature = -BitUtil.to(temperature, 7); - } - position.set(Position.PREFIX_TEMP + 1, temperature); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); - } - } - - if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4) && buf.readableBytes() >= 3 + 6) { - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); - } - - if (type == MSG_GPS_LBS_3) { - int module = buf.readUnsignedShort(); - int length = buf.readUnsignedByte(); - switch (module) { - case 0x0027: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - break; - case 0x002E: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - break; - case 0x003B: - position.setAccuracy(buf.readUnsignedShort() * 0.01); - break; - default: - buf.skipBytes(length); - break; - } - } - - if (buf.readableBytes() == 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } - } - private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); @@ -1017,7 +946,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { data = buf.readSlice(buf.readableBytes() - 6).toString(StandardCharsets.UTF_16BE); } - if (decodeLocationString(position, data) == null) { + Parser parser = new Parser(PATTERN_LOCATION, data); + + if (parser.matches()) { + position.setValid(true); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setCourse(parser.nextDouble()); + position.setSpeed(parser.nextDouble()); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); + } else { getLastLocation(position, null); position.set(Position.KEY_RESULT, data); } @@ -1031,31 +969,50 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); if (subType == 0x00) { + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.01); return position; + } else if (subType == 0x05) { + int flags = buf.readUnsignedByte(); position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); return position; + } else if (subType == 0x0a) { + buf.skipBytes(8); // imei buf.skipBytes(8); // imsi position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10)).replaceAll("f", "")); return position; + } else if (subType == 0x0d) { + if (buf.getByte(buf.readerIndex()) != '!') { buf.skipBytes(6); } - return decodeFuelData(position, buf.toString( + + Parser parser = new Parser(PATTERN_FUEL, buf.toString( buf.readerIndex(), buf.readableBytes() - 4 - 2, StandardCharsets.US_ASCII)); + if (!parser.matches()) { + return null; + } + + position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); + position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); + + return position; + } else if (subType == 0x1b) { + buf.readUnsignedByte(); // header buf.readUnsignedByte(); // type position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); buf.readUnsignedByte(); // checksum buf.readUnsignedByte(); // footer return position; + } } else if (type == MSG_X1_PHOTO_DATA) { @@ -1170,132 +1127,111 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { - return decodeExtendedModular(channel, buf, deviceSession); - - } else { - - return decodeExtendedOther(channel, buf, deviceSession, type); - - } - - return null; - } - - private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - while (buf.readableBytes() > 6) { - int moduleType = buf.readUnsignedShort(); - int moduleLength = buf.readUnsignedShort(); + while (buf.readableBytes() > 6) { + int moduleType = buf.readUnsignedShort(); + int moduleLength = buf.readUnsignedShort(); - switch (moduleType) { - case 0x03: - position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); - break; - case 0x09: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x0a: - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); - break; - case 0x11: - CellTower cellTower = CellTower.from( - buf.readUnsignedShort(), - buf.readUnsignedShort(), - buf.readUnsignedShort(), - buf.readUnsignedMedium(), - buf.readUnsignedByte()); - if (cellTower.getCellId() > 0) { - position.setNetwork(new Network(cellTower)); - } - break; - case 0x18: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); - break; - case 0x28: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x29: - position.set(Position.KEY_INDEX, buf.readUnsignedInt()); - break; - case 0x2a: - int input = buf.readUnsignedByte(); - position.set(Position.KEY_DOOR, BitUtil.to(input, 4) > 0); - position.set("tamper", BitUtil.from(input, 4) > 0); - break; - case 0x2b: - int event = buf.readUnsignedByte(); - switch (event) { - case 0x11: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case 0x12: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case 0x13: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case 0x14: - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); - break; - default: - break; - } - position.set(Position.KEY_EVENT, event); - break; - case 0x2e: - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0x33: - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.setAltitude(buf.readShort()); - - double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; - double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - int flags = buf.readUnsignedShort(); - position.setCourse(BitUtil.to(flags, 10)); - position.setValid(BitUtil.check(flags, 12)); - - if (!BitUtil.check(flags, 10)) { - latitude = -latitude; - } - if (BitUtil.check(flags, 11)) { - longitude = -longitude; - } - - position.setLatitude(latitude); - position.setLongitude(longitude); - break; - case 0x34: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - buf.readUnsignedIntLE(); // time - buf.skipBytes(buf.readUnsignedByte()); // content - break; - default: - buf.skipBytes(moduleLength); - break; + switch (moduleType) { + case 0x03: + position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); + break; + case 0x09: + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + break; + case 0x0a: + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); + break; + case 0x11: + CellTower cellTower = CellTower.from( + buf.readUnsignedShort(), + buf.readUnsignedShort(), + buf.readUnsignedShort(), + buf.readUnsignedMedium(), + buf.readUnsignedByte()); + if (cellTower.getCellId() > 0) { + position.setNetwork(new Network(cellTower)); + } + break; + case 0x18: + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + break; + case 0x28: + position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + break; + case 0x29: + position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + break; + case 0x2a: + int input = buf.readUnsignedByte(); + position.set(Position.KEY_DOOR, BitUtil.to(input, 4) > 0); + position.set("tamper", BitUtil.from(input, 4) > 0); + break; + case 0x2b: + int event = buf.readUnsignedByte(); + switch (event) { + case 0x11: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + break; + case 0x12: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + break; + case 0x13: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; + case 0x14: + position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + break; + default: + break; + } + position.set(Position.KEY_EVENT, event); + break; + case 0x2e: + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + break; + case 0x33: + position.setTime(new Date(buf.readUnsignedInt() * 1000)); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.setAltitude(buf.readShort()); + + double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; + double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + + int flags = buf.readUnsignedShort(); + position.setCourse(BitUtil.to(flags, 10)); + position.setValid(BitUtil.check(flags, 12)); + + if (!BitUtil.check(flags, 10)) { + latitude = -latitude; + } + if (BitUtil.check(flags, 11)) { + longitude = -longitude; + } + + position.setLatitude(latitude); + position.setLongitude(longitude); + break; + case 0x34: + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + buf.readUnsignedIntLE(); // time + buf.skipBytes(buf.readUnsignedByte()); // content + break; + default: + buf.skipBytes(moduleLength); + break; + } } - } - if (position.getFixTime() == null) { - getLastLocation(position, null); - } - - sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - - return position; - } + if (position.getFixTime() == null) { + getLastLocation(position, null); + } - private Object decodeExtendedOther(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { + sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - Position position = null; + return position; - if (type == MSG_MULTIMEDIA || type == MSG_MULTIMEDIA_2) { + } else if (type == MSG_MULTIMEDIA || type == MSG_MULTIMEDIA_2) { buf.skipBytes(8); // serial number long timestamp = buf.readUnsignedInt() * 1000; -- cgit v1.2.3 From c10e8132c4dc4a78b3440725516ffaaec6834406 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Apr 2022 13:27:51 -0700 Subject: Decode GT06 variants --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 52 +++++++++++++--------- 1 file changed, 31 insertions(+), 21 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 325527f06..89931f614 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1,5 +1,5 @@ /* -Supp * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -107,14 +107,17 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_OBD = 0x8C; // FM08ABC public static final int MSG_DTC = 0x65; // FM08ABC public static final int MSG_PID = 0x66; // FM08ABC - public static final int MSG_BMS = 0x20; // WD-209 - public static final int MSG_MULTIMEDIA = 0x21; // WD-209 - public static final int MSG_BMS_2 = 0x40; // WD-209 - public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 + public static final int MSG_BMS = 0x40; // WD-209 + public static final int MSG_MULTIMEDIA = 0x41; // WD-209 public static final int MSG_ALARM = 0x95; // JC100 private enum Variant { VXT01, + WANWAY_S20, + GT06E_CARD, + BENWAY, + S5, + SPACE10X, STANDARD, } @@ -472,7 +475,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { deviceSession.setTimeZone(timeZone); } } - } if (deviceSession != null) { @@ -646,10 +648,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type == MSG_LBS_STATUS && dataLength >= 18) { - - return null; // space10x multi-lbs message - } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { @@ -662,9 +660,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, dateBuilder.getDate()); - boolean hasCellCount = type == MSG_LBS_MULTIPLE_3 && dataLength == 44; - - if (hasCellCount) { + if (variant == Variant.WANWAY_S20) { buf.readUnsignedByte(); // ta } @@ -672,7 +668,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); Network network = new Network(); - int cellCount = hasCellCount ? buf.readUnsignedByte() : type == MSG_WIFI_5 ? 6 : 7; + int cellCount = variant == Variant.WANWAY_S20 ? buf.readUnsignedByte() : type == MSG_WIFI_5 ? 6 : 7; for (int i = 0; i < cellCount; i++) { int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); @@ -682,7 +678,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - if (!hasCellCount) { + if (variant != Variant.WANWAY_S20) { buf.readUnsignedByte(); // ta } @@ -714,7 +710,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - } else if (type == MSG_BMS || type == MSG_BMS_2) { + } else if (type == MSG_BMS) { buf.skipBytes(8); // serial number @@ -769,6 +765,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (isSupported(type)) { + if (type == MSG_LBS_STATUS && variant == Variant.SPACE10X) { + return null; // multi-lbs message + } + if (hasGps(type)) { decodeGps(position, buf, false, deviceSession.getTimeZone()); } else { @@ -785,13 +785,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (type == MSG_GPS_LBS_1) { - if (buf.readableBytes() > 75 + 6) { + if (variant == Variant.GT06E_CARD) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); buf.readUnsignedByte(); // alarm buf.readUnsignedByte(); // swiped position.set("driverLicense", data.trim()); - } else if (buf.readableBytes() == 8) { + } else if (variant == Variant.BENWAY) { int mask = buf.readUnsignedShort(); position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); @@ -809,10 +809,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 1, value * 0.1); } } - } else if (buf.readableBytes() == 11) { + } else if (variant == Variant.VXT01) { decodeStatus(position, buf, false); buf.readUnsignedByte(); // alarm extension - } else if (buf.readableBytes() == 18) { + } else if (variant == Variant.S5) { decodeStatus(position, buf, false); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("oil", buf.readUnsignedShort()); @@ -1231,7 +1231,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type == MSG_MULTIMEDIA || type == MSG_MULTIMEDIA_2) { + } else if (type == MSG_MULTIMEDIA) { buf.skipBytes(8); // serial number long timestamp = buf.readUnsignedInt() * 1000; @@ -1322,6 +1322,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_1 && length == 0x24) { variant = Variant.VXT01; + } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x31) { + variant = Variant.WANWAY_S20; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length >= 0x71) { + variant = Variant.GT06E_CARD; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x21) { + variant = Variant.BENWAY; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x2b) { + variant = Variant.S5; + } else if (header == 0x7878 && type == MSG_LBS_STATUS && length >= 0x17) { + variant = Variant.SPACE10X; } else { variant = Variant.STANDARD; } -- cgit v1.2.3 From 94fa65d6961fc369923b11a60758b83ac7c3ecae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 30 Apr 2022 09:30:43 -0700 Subject: Fix Envotech location --- src/main/java/org/traccar/helper/Parser.java | 5 +++++ .../traccar/protocol/EnvotechProtocolDecoder.java | 21 ++++++++++++++++----- .../protocol/EnvotechProtocolDecoderTest.java | 3 ++- 3 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/Parser.java b/src/main/java/org/traccar/helper/Parser.java index 75106e2ba..22e98ded1 100644 --- a/src/main/java/org/traccar/helper/Parser.java +++ b/src/main/java/org/traccar/helper/Parser.java @@ -155,6 +155,7 @@ public class Parser { public enum CoordinateFormat { DEG_DEG, + DEG_DEG_HEM, DEG_HEM, DEG_MIN_MIN, DEG_MIN_HEM, @@ -173,6 +174,10 @@ public class Parser { case DEG_DEG: coordinate = Double.parseDouble(next() + '.' + next()); break; + case DEG_DEG_HEM: + coordinate = Double.parseDouble(next() + '.' + next()); + hemisphere = next(); + break; case DEG_HEM: coordinate = nextDouble(0); hemisphere = next(); diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 083d8a921..51391d4cc 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -54,8 +54,8 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { .number("(dd)(dd)(dd)") // date (ddmmyy) .number("(dd)(dd)(dd)") // time (hhmmss) .number("(d)") // fix - .number("(dd)(dd)(d+)([NS])") // latitude - .number("(ddd)(dd)(d+)([EW])") // longitude + .number("(d+)(d{5})([NS])") // latitude + .number("(d+)(d{5})([EW])") // longitude .number("(ddd)") // speed .number("(ddd)") // course .any() @@ -72,7 +72,18 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); - position.set(Position.KEY_EVENT, parser.nextHexInt()); + int event = parser.nextHexInt(); + switch (event) { + case 0x60: + position.set(Position.KEY_ALARM, Position.ALARM_LOCK); + break; + case 0x61: + position.set(Position.KEY_ALARM, Position.ALARM_UNLOCK); + break; + default: + break; + } + position.set(Position.KEY_EVENT, event); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { @@ -92,8 +103,8 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); position.setValid(parser.nextInt() > 0); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG_HEM)); position.setSpeed(parser.nextInt()); position.setCourse(parser.nextInt()); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 6a455975d..60c592e1e 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -11,7 +11,8 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { var decoder = new EnvotechProtocolDecoder(null); verifyPosition(decoder, text( - "$80SLM,02,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281*2A")); + "$80SLM,02,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281*2A"), + position("2010-04-13 15:59:21.000", true, 4.76673, 101.11459)); verifyPosition(decoder, text( "$80SLM,82,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281@B0,F,C456,038,00,M234567,,,1A2A3A4A5A6A*4E")); -- cgit v1.2.3 From 2a6e75c5d9527cb7b5b54e257fd756e717d5347a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 30 Apr 2022 18:29:37 -0700 Subject: Implement cluster broadcasting --- debug.xml | 3 + src/main/java/org/traccar/Context.java | 11 +++ src/main/java/org/traccar/Main.java | 15 ++-- src/main/java/org/traccar/MainEventHandler.java | 10 +++ .../org/traccar/broadcast/BroadcastMessage.java | 42 +++++++++ .../org/traccar/broadcast/BroadcastService.java | 100 +++++++++++++++++++++ .../java/org/traccar/broadcast/DeviceStatus.java | 52 +++++++++++ src/main/java/org/traccar/config/Keys.java | 14 +++ 8 files changed, 241 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/traccar/broadcast/BroadcastMessage.java create mode 100644 src/main/java/org/traccar/broadcast/BroadcastService.java create mode 100644 src/main/java/org/traccar/broadcast/DeviceStatus.java (limited to 'src/main/java/org') diff --git a/debug.xml b/debug.xml index f9515bb2b..29ece6260 100644 --- a/debug.xml +++ b/debug.xml @@ -20,4 +20,7 @@ true 6037 + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index aeba9c4c9..c44d432b2 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import org.apache.velocity.app.VelocityEngine; import org.eclipse.jetty.util.URIUtil; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.AttributesManager; @@ -171,6 +172,12 @@ public final class Context { return scheduleManager; } + private static BroadcastService broadcastService; + + public static BroadcastService getBroadcastService() { + return broadcastService; + } + private static GeofenceManager geofenceManager; public static GeofenceManager getGeofenceManager() { @@ -335,6 +342,10 @@ public final class Context { serverManager = new ServerManager(); scheduleManager = new ScheduleManager(); + if (config.hasKey(Keys.BROADCAST_ADDRESS)) { + broadcastService = new BroadcastService(config, objectMapper); + } + if (config.hasKey(Keys.EVENT_FORWARD_URL)) { eventForwarder = new EventForwarder(); } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 6daf72bb4..2eaf394af 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -118,13 +118,14 @@ public final class Main { List services = new LinkedList<>(); services.add(Context.getServerManager()); - if (Context.getWebServer() != null) { - services.add(Context.getWebServer()); - } + services.add(Context.getWebServer()); services.add(Context.getScheduleManager()); + services.add(Context.getBroadcastService()); for (LifecycleObject service : services) { - service.start(); + if (service != null) { + service.start(); + } } Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.error("Thread exception", e)); @@ -134,7 +135,9 @@ public final class Main { Collections.reverse(services); for (LifecycleObject service : services) { - service.stop(); + if (service != null) { + service.stop(); + } } })); } catch (Exception e) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index a3f6f4105..0e60ac06d 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,12 +23,14 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.broadcast.BroadcastMessage; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -61,6 +63,14 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.warn("Failed to update device", error); } + BroadcastMessage message = new BroadcastMessage(); + message.setPosition(position); + try { + Context.getBroadcastService().sendMessage(message); + } catch (IOException e) { + e.printStackTrace(); + } + String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); StringBuilder builder = new StringBuilder(); diff --git a/src/main/java/org/traccar/broadcast/BroadcastMessage.java b/src/main/java/org/traccar/broadcast/BroadcastMessage.java new file mode 100644 index 000000000..6b103f373 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/BroadcastMessage.java @@ -0,0 +1,42 @@ +/* + * 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.broadcast; + +import org.traccar.model.Position; + +public class BroadcastMessage { + + private DeviceStatus deviceStatus; + + public DeviceStatus getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(DeviceStatus deviceStatus) { + this.deviceStatus = deviceStatus; + } + + private Position position; + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + +} diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java new file mode 100644 index 000000000..b17857fcd --- /dev/null +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -0,0 +1,100 @@ +/* + * 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.broadcast; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.LifecycleObject; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class BroadcastService implements LifecycleObject { + + private static final Logger LOGGER = LoggerFactory.getLogger(BroadcastService.class); + + private final ObjectMapper objectMapper; + + private final InetAddress address; + private final int port; + + private DatagramSocket publisherSocket; + + private final ExecutorService service = Executors.newSingleThreadExecutor(); + private final byte[] receiverBuffer = new byte[4096]; + + @Inject + public BroadcastService(Config config, ObjectMapper objectMapper) throws IOException { + this.objectMapper = objectMapper; + address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); + port = config.getInteger(Keys.BROADCAST_PORT); + } + + public void sendMessage(BroadcastMessage message) throws IOException { + byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); + publisherSocket.send(packet); + } + + private void handleMessage(BroadcastMessage message) { + if (message.getDeviceStatus() != null) { + LOGGER.info("Broadcast received device {}", message.getDeviceStatus().getDeviceId()); + } else if (message.getPosition() != null) { + LOGGER.info("Broadcast received position {}", message.getPosition().getDeviceId()); + } + } + + @Override + public void start() throws IOException { + service.submit(receiver); + publisherSocket = new DatagramSocket(); + } + + @Override + public void stop() { + publisherSocket.close(); + service.shutdown(); + } + + private final Runnable receiver = new Runnable() { + @Override + public void run() { + try (MulticastSocket socket = new MulticastSocket(port)) { + socket.joinGroup(address); + while (!service.isShutdown()) { + DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); + socket.receive(packet); + String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + } + socket.leaveGroup(address); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }; + +} diff --git a/src/main/java/org/traccar/broadcast/DeviceStatus.java b/src/main/java/org/traccar/broadcast/DeviceStatus.java new file mode 100644 index 000000000..4f0143319 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/DeviceStatus.java @@ -0,0 +1,52 @@ +/* + * 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.broadcast; + +import java.util.Date; + +public class DeviceStatus { + + private long deviceId; + + public long getDeviceId() { + return deviceId; + } + + public void setDeviceId(long deviceId) { + this.deviceId = deviceId; + } + + private String status; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + private Date lastUpdate; + + public Date getLastUpdate() { + return this.lastUpdate; + } + + public void setLastUpdate(Date lastUpdate) { + this.lastUpdate = lastUpdate; + } + +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ccfe4bee7..dc6bcbec9 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1309,4 +1309,18 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL), "time,position,speed,course,accuracy,result"); + /** + * Multicast address for broadcasting synchronization events. + */ + public static final ConfigKey BROADCAST_ADDRESS = new ConfigKey<>( + "broadcast.address", + Collections.singletonList(KeyType.GLOBAL)); + + /** + * Multicast port for broadcasting synchronization events. + */ + public static final ConfigKey BROADCAST_PORT = new ConfigKey<>( + "broadcast.port", + Collections.singletonList(KeyType.GLOBAL)); + } -- cgit v1.2.3 From 19869710f012cbf1a32063021d59aa2d58688e6b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 May 2022 16:02:11 -0700 Subject: Remove test broadcase --- src/main/java/org/traccar/MainEventHandler.java | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 0e60ac06d..a3f6f4105 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,14 +23,12 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.broadcast.BroadcastMessage; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; -import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -63,14 +61,6 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.warn("Failed to update device", error); } - BroadcastMessage message = new BroadcastMessage(); - message.setPosition(position); - try { - Context.getBroadcastService().sendMessage(message); - } catch (IOException e) { - e.printStackTrace(); - } - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); StringBuilder builder = new StringBuilder(); -- cgit v1.2.3 From 9633eccdead886ed0b580707ad76cdf06df9a603 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 May 2022 08:22:53 -0700 Subject: Log transport layer protocol --- src/main/java/org/traccar/BaseProtocolEncoder.java | 3 ++- src/main/java/org/traccar/MainEventHandler.java | 17 +++++------- .../traccar/handler/StandardLoggingHandler.java | 8 +++--- src/main/java/org/traccar/helper/NetworkUtil.java | 31 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/traccar/helper/NetworkUtil.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index b6df07b98..71fa61e4e 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -21,6 +21,7 @@ import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.helper.NetworkUtil; import org.traccar.model.Command; public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { @@ -62,7 +63,7 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter Object encodedCommand = encodeCommand(ctx.channel(), command); StringBuilder s = new StringBuilder(); - s.append("[").append(ctx.channel().id().asShortText()).append("] "); + s.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); s.append("id: ").append(getUniqueId(command.getDeviceId())).append(", "); s.append("command type: ").append(command.getType()).append(" "); if (encodedCommand != null) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index a3f6f4105..f1f2527bc 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; +import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; @@ -64,7 +65,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); StringBuilder builder = new StringBuilder(); - builder.append(formatChannel(ctx.channel())).append(" "); + builder.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); builder.append("id: ").append(uniqueId); for (String attribute : logAttributes) { switch (attribute) { @@ -113,20 +114,16 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { } } - private static String formatChannel(Channel channel) { - return String.format("[%s]", channel.id().asShortText()); - } - @Override public void channelActive(ChannelHandlerContext ctx) { if (!(ctx.channel() instanceof DatagramChannel)) { - LOGGER.info(formatChannel(ctx.channel()) + " connected"); + LOGGER.info("[{}] connected", NetworkUtil.session(ctx.channel())); } } @Override public void channelInactive(ChannelHandlerContext ctx) { - LOGGER.info(formatChannel(ctx.channel()) + " disconnected"); + LOGGER.info("[{}] disconnected", NetworkUtil.session(ctx.channel())); closeChannel(ctx.channel()); if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null @@ -140,14 +137,14 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { while (cause.getCause() != null && cause.getCause() != cause) { cause = cause.getCause(); } - LOGGER.warn(formatChannel(ctx.channel()) + " error", cause); + LOGGER.info("[{}] error", NetworkUtil.session(ctx.channel()), cause); closeChannel(ctx.channel()); } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt instanceof IdleStateEvent) { - LOGGER.info(formatChannel(ctx.channel()) + " timed out"); + LOGGER.info("[{}] timed out", NetworkUtil.session(ctx.channel())); closeChannel(ctx.channel()); } } diff --git a/src/main/java/org/traccar/handler/StandardLoggingHandler.java b/src/main/java/org/traccar/handler/StandardLoggingHandler.java index 13c5f8281..84492e2a5 100644 --- a/src/main/java/org/traccar/handler/StandardLoggingHandler.java +++ b/src/main/java/org/traccar/handler/StandardLoggingHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 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. @@ -23,6 +23,7 @@ import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.NetworkMessage; +import org.traccar.helper.NetworkUtil; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -63,7 +64,7 @@ public class StandardLoggingHandler extends ChannelDuplexHandler { public void log(ChannelHandlerContext ctx, boolean downstream, SocketAddress remoteAddress, ByteBuf buf) { StringBuilder message = new StringBuilder(); - message.append("[").append(ctx.channel().id().asShortText()).append(": "); + message.append("[").append(NetworkUtil.session(ctx.channel())).append(": "); message.append(protocol); if (downstream) { message.append(" > "); @@ -76,9 +77,8 @@ public class StandardLoggingHandler extends ChannelDuplexHandler { } else { message.append("unknown"); } - message.append("]"); + message.append("] "); - message.append(" HEX: "); message.append(ByteBufUtil.hexDump(buf)); LOGGER.info(message.toString()); diff --git a/src/main/java/org/traccar/helper/NetworkUtil.java b/src/main/java/org/traccar/helper/NetworkUtil.java new file mode 100644 index 000000000..2fe3487da --- /dev/null +++ b/src/main/java/org/traccar/helper/NetworkUtil.java @@ -0,0 +1,31 @@ +/* + * 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.helper; + +import io.netty.channel.Channel; +import io.netty.channel.socket.DatagramChannel; + +public final class NetworkUtil { + + private NetworkUtil() { + } + + public static String session(Channel channel) { + char transport = channel instanceof DatagramChannel ? 'U' : 'T'; + return transport + channel.id().asShortText(); + } + +} -- cgit v1.2.3 From 8853720199fb97d31d61cb442b5eac2d547aa8a0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 May 2022 08:35:18 -0700 Subject: Fix Envotech status decoding --- src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 51391d4cc..347063547 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -99,7 +99,7 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_INPUT, parser.nextHexInt()); position.set(Position.PREFIX_OUT, parser.nextHexInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); - position.set(Position.KEY_STATUS, parser.nextHexInt()); + position.set(Position.KEY_STATUS, parser.nextHexLong()); position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); position.setValid(parser.nextInt() > 0); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 60c592e1e..70fb5a188 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { var decoder = new EnvotechProtocolDecoder(null); + verifyPosition(decoder, text( + "$80SLM,62,000F,F015727,020522053200,611000000,000391,C080,000,80028900,85010000'02052205320110399426S03970217E000145*E0C2#")); + verifyPosition(decoder, text( "$80SLM,02,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281*2A"), position("2010-04-13 15:59:21.000", true, 4.76673, 101.11459)); -- cgit v1.2.3 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 + src/main/java/org/traccar/Context.java | 4 +++- src/main/java/org/traccar/config/Keys.java | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') 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 diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index c44d432b2..ee14f8a1a 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -294,7 +294,9 @@ public final class Context { } objectMapper = new ObjectMapper(); - objectMapper.registerModule(new SanitizerModule()); + if (config.getBoolean(Keys.WEB_SANITIZE)) { + objectMapper.registerModule(new SanitizerModule()); + } objectMapper.registerModule(new JSR353Module()); objectMapper.setConfig( objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index dc6bcbec9..f5299b90b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -552,6 +552,14 @@ public final class Keys { "web.port", Collections.singletonList(KeyType.GLOBAL)); + /** + * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based + * interface doesn't require this. + */ + public static final ConfigKey WEB_SANITIZE = new ConfigKey<>( + "web.sanitize", + Collections.singletonList(KeyType.GLOBAL)); + /** * Path to the web app folder. */ -- cgit v1.2.3 From b8f0c159aa3e13e902305e4b68ad7f851696b69c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 6 May 2022 15:00:06 -0700 Subject: Add timezones API --- src/main/java/org/traccar/api/resource/ServerResource.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 2d17d5e47..f238e8905 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -34,6 +34,9 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.Arrays; +import java.util.Collection; +import java.util.TimeZone; @Path("server") @Produces(MediaType.APPLICATION_JSON) @@ -67,4 +70,10 @@ public class ServerResource extends BaseResource { } } + @Path("timezones") + @GET + public Collection timezones() { + return Arrays.asList(TimeZone.getAvailableIDs()); + } + } -- cgit v1.2.3 From 78a3d28440b4de89eaab79664fef512e6e869030 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 12 May 2022 17:19:32 -0700 Subject: Support Envotech IVM format --- src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java | 4 +++- src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 347063547..65d5e3859 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -48,7 +48,8 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { .number("(ddd),") // battery .number("(xx)") // inputs .number("(xx),") // outputs - .number("(xxx)?,") // fuel + .number("(xxx)?") // fuel + .number("(xxx)?,") // weight .number("(x{8}),") // status .expression("[^']*'") .number("(dd)(dd)(dd)") // date (ddmmyy) @@ -99,6 +100,7 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_INPUT, parser.nextHexInt()); position.set(Position.PREFIX_OUT, parser.nextHexInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); + position.set("weight", parser.nextHexInt()); position.set(Position.KEY_STATUS, parser.nextHexLong()); position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 70fb5a188..0809a1e9a 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { var decoder = new EnvotechProtocolDecoder(null); + verifyPosition(decoder, text( + "$80IVM,03,E002215,E002215,110422061936,672763902,126423,0180,000000,00018600,0.0000'11042206193710406325S03966094E000118*42D6#")); + verifyPosition(decoder, text( "$80SLM,62,000F,F015727,020522053200,611000000,000391,C080,000,80028900,85010000'02052205320110399426S03970217E000145*E0C2#")); -- cgit v1.2.3 From 7a0e14eda651314d7bd076c882dd872964b16832 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 12 May 2022 17:51:48 -0700 Subject: Decode Wireless Links cell data --- .../org/traccar/protocol/WliProtocolDecoder.java | 74 ++++++++++++++++++---- .../traccar/protocol/WliProtocolDecoderTest.java | 3 + 2 files changed, 65 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java index 0e2a0a65e..976d4fb27 100644 --- a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WliProtocolDecoder.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. @@ -22,6 +22,8 @@ import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; @@ -41,9 +43,9 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // header - int type = buf.readUnsignedByte(); + int clazz = buf.readUnsignedByte(); - if (type == '1') { + if (clazz == '1') { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -53,11 +55,13 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + CellTower cellTower = new CellTower(); + position.set(Position.KEY_INDEX, buf.readUnsignedShort()); buf.readUnsignedShort(); // length buf.readUnsignedShort(); // checksum - buf.readUnsignedByte(); // application message type + int type = buf.readUnsignedByte(); buf.readUnsignedByte(); // delimiter while (buf.readableBytes() > 1) { @@ -95,18 +99,56 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { String value = buf.readCharSequence( endIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString(); - switch (fieldNumber) { - case 246: - String[] values = value.split(","); - position.set(Position.KEY_POWER, Integer.parseInt(values[2]) * 0.01); - position.set(Position.KEY_BATTERY, Integer.parseInt(values[3]) * 0.01); + int networkFieldsOffset; + switch (type) { + case 0xE4: + networkFieldsOffset = 10; + break; + case 0xCB: + networkFieldsOffset = 80; break; - case 255: - position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + case 0x1E: + networkFieldsOffset = 182; break; + case 0xC9: default: + networkFieldsOffset = 35; break; } + if (fieldNumber - networkFieldsOffset >= 0 && fieldNumber - networkFieldsOffset < 10) { + switch (fieldNumber - networkFieldsOffset) { + case 0: + cellTower.setMobileCountryCode(Integer.parseInt(value)); + break; + case 1: + cellTower.setMobileNetworkCode(Integer.parseInt(value)); + break; + case 2: + cellTower.setLocationAreaCode(Integer.parseInt(value)); + break; + case 3: + cellTower.setCellId(Long.parseLong(value)); + break; + case 4: + cellTower.setSignalStrength(Integer.parseInt(value)); + break; + default: + break; + } + } else { + switch (fieldNumber) { + case 246: + String[] values = value.split(","); + position.set(Position.KEY_POWER, Integer.parseInt(values[2]) * 0.01); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[3]) * 0.01); + break; + case 255: + position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + break; + default: + break; + } + } } @@ -114,13 +156,21 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { } + if (type == 0xE4) { + getLastLocation(position, position.getDeviceTime()); + } + + if (cellTower.getCellId() != null) { + position.setNetwork(new Network(cellTower)); + } + if (!position.getValid()) { getLastLocation(position, position.getDeviceTime()); } return position; - } else if (type == '2') { + } else if (clazz == '2') { String id = buf.toString(buf.readerIndex(), buf.readableBytes() - 1, StandardCharsets.US_ASCII); getDeviceSession(channel, remoteAddress, id.substring("wli:".length())); diff --git a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java index 6f86a9fd9..77184f86a 100644 --- a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class WliProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "0232776c693a30343930333332303332343103")); + verifyAttributes(decoder, binary( + "0231000101536c27e40001003400dbd20030363a34323a303000dbd30030352f30322f31390004002d3100060030000a00343235000b003031000c003130343232000d003336343733000e003239000f0037001000312c312c312c312c31302e3230322e33342e33312c36353533352c302c39392c39392c3235352c3235352c3235352c323535001100300013003000140033001500343237001600333700170031001800313038001900320031003000320030004500302c323031392f30352f30322c30363a34313a34312c323031392f30352f30322c30363a33353a303800f100342c302c332c302c2d312c2d3100f2003300f3003100f50038363634323530333137303639323400f600312c302c302c3431322c3000f70038343437373200f800302c3330302c302c302c302c302c2c2c2c2c2c302c3000f9003300fa00393100fb0032313100fc0032313000ff00313535363737393332300003")); + verifyPosition(decoder, binary( "0231000101bba758c900010034000500ff001001258fc9013e80ed00001183350101e20006003200090030000a0032000b003331000c0031000d00343438000e003530000f003100100031303800130032001b003134001c0033392c33352c32382c33382c34302c33372c33332c33382c33352c34322c33372c3335001d003130001e0038002300343235002400303100250031303432320026003336343733002700323800280037002900312c312c312c312c31302e3232352e3135312e3230342c36353533352c302c39392c39392c3235352c3235352c3235352c323535002a0030002c0030003000300032003000330031003400ff001c0214130502061b0101258fc9013e80ed000001e2000000000000004d004500302c323031392f30352f30322c30363a33333a30302c323031392f30352f30322c30363a32363a3230005a003000f100352c302c342c302c2d312c2d3100f2003300f3003100f50038363634323530333137303639323400f600312c302c302c3431322c3000f70038343437373200f80032312c31312c302c302c302c302c2c2c2c2c2c302c3000f9003300fa00393100fb0032313100fc0032313000ff00313535363737383533340003")); -- cgit v1.2.3 From bac331ebf2a67d0bdc4f96c78f0dfbeb0c4b6da6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 15 May 2022 16:58:10 -0700 Subject: Handle Startek OBD issue --- src/main/java/org/traccar/protocol/StartekProtocolDecoder.java | 4 +++- src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index c1869def2..8a7b5cec7 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -42,7 +42,6 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("d+,") // length .number("(d+),") // imei .expression("(.+)") // content - .number("xx") // checksum .compile(); private static final Pattern PATTERN_POSITION = new PatternBuilder() @@ -123,6 +122,9 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } String content = parser.next(); + if (content.charAt(content.length() - 2 - 1) != '|') { + content = content.substring(0, content.length() - 2); + } if (content.length() < 100) { Position position = new Position(getProtocolName()); diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index 6c2d39940..cea079156 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,8 +11,9 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = new StartekProtocolDecoder(null); - verifyPosition(decoder, text( - "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52")); + verifyAttribute(decoder, text( + "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52"), + Position.KEY_FUEL_LEVEL, 52); verifyPosition(decoder, text( "&&o142,860262050066062,000,27,,211111070826,V,28.653435,-106.077455,0,0.0,0,151,1412,918,0|0|4708|01402D19,6,0000001A,02,00,04C0|016C|0000|0000,1,,,BB")); -- cgit v1.2.3 From 823795e40bf9b029a5c6c80fe58744244d24a5c7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 16 May 2022 17:29:52 -0700 Subject: Add Concox/Jimi VL502 transparent data --- .../traccar/protocol/HuabaoProtocolDecoder.java | 157 +++++++++++++++++++-- .../protocol/HuabaoProtocolDecoderTest.java | 3 + 2 files changed, 145 insertions(+), 15 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index b0ad9a229..c280ee9b2 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -64,6 +64,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TIME_SYNC_REQUEST = 0x0109; public static final int MSG_TIME_SYNC_RESPONSE = 0x8109; public static final int MSG_PHOTO = 0x8888; + public static final int MSG_TRANSPARENT = 0x0900; public static final int RESULT_SUCCESS = 0; @@ -148,6 +149,17 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return BitUtil.check(value, 15) ? -BitUtil.to(value, 15) : BitUtil.to(value, 15); } + private Date readDate(ByteBuf buf, TimeZone timeZone) { + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setYear(BcdUtil.readInteger(buf, 2)) + .setMonth(BcdUtil.readInteger(buf, 2)) + .setDay(BcdUtil.readInteger(buf, 2)) + .setHour(BcdUtil.readInteger(buf, 2)) + .setMinute(BcdUtil.readInteger(buf, 2)) + .setSecond(BcdUtil.readInteger(buf, 2)); + return dateBuilder.getDate(); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -267,6 +279,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_TRANSPARENT) { + + return decodeTransparent(deviceSession, buf); + } return null; @@ -354,12 +370,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); + private void decodeCoordinates(Position position, ByteBuf buf) { int status = buf.readInt(); @@ -382,19 +393,21 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } else { position.setLongitude(lon); } + } + + private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); + + decodeCoordinates(position, buf); position.setAltitude(buf.readShort()); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort()); - - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) - .setYear(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); + position.setTime(readDate(buf, deviceSession.getTimeZone())); if (buf.readableBytes() == 20) { @@ -609,4 +622,118 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return positions; } + private Position decodeTransparent(DeviceSession deviceSession, ByteBuf buf) { + + int type = buf.readUnsignedByte(); + + if (type == 0xF0) { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + Date time = readDate(buf, deviceSession.getTimeZone()); + + if (buf.readUnsignedByte() > 0) { + position.set(Position.KEY_ARCHIVE, true); + } + + buf.readUnsignedByte(); // vehicle type + + int count; + int subtype = buf.readUnsignedByte(); + switch (subtype) { + case 0x01: + count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + int id = buf.readUnsignedShort(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x0102: + case 0x0528: + case 0x0546: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); + break; + case 0x0103: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedInt() * 0.01); + break; + case 0x052A: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.01); + break; + case 0x0105: + case 0x052C: + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.01); + break; + case 0x014A: + case 0x0537: + case 0x0538: + case 0x0539: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); + break; + default: + switch (length) { + case 1: + position.set(Position.PREFIX_IO + id, buf.readUnsignedByte()); + break; + case 2: + position.set(Position.PREFIX_IO + id, buf.readUnsignedShort()); + break; + case 4: + position.set(Position.PREFIX_IO + id, buf.readUnsignedInt()); + break; + default: + buf.skipBytes(length); + break; + } + break; + } + } + decodeCoordinates(position, buf); + position.setTime(time); + break; + case 0x03: + count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + int id = buf.readUnsignedShort(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x1A: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 0x1B: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 0x1C: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + case 0x1D: + case 0x1E: + case 0x1F: + position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); + break; + case 0x23: + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + break; + default: + break; + } + buf.skipBytes(length); + } + decodeCoordinates(position, buf); + position.setTime(time); + break; + case 0x0B: + if (buf.readUnsignedByte() > 0) { + position.set(Position.KEY_VIN, buf.readCharSequence(17, StandardCharsets.US_ASCII).toString()); + } + getLastLocation(position, time); + break; + default: + return null; + } + + return position; + } + + return null; + } + } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 8ba6fcaf1..d61dae315 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); + verifyPosition(decoder, binary( + "7E0900005A4E5DE66FBA2200C4F02204280610090002010D052B0150052C0400129009052D016B052E014F05300231BA053502000005360203B8053802000005390200AD053D0201EA05440150054604009899D90545040000001E000C00030160A85C06D1C1389C7E")); + verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); -- cgit v1.2.3 From dcdbbf298e91e04c36c0310ac9c3314000d8781f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 16 May 2022 17:46:25 -0700 Subject: Support Farnear alarms --- .../org/traccar/protocol/GotopProtocolDecoder.java | 19 +++++++++++++++---- .../traccar/protocol/GotopProtocolDecoderTest.java | 14 +++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java index a867451aa..0f8d29228 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -35,7 +35,7 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("(d+),") // imei - .expression("[^,]+,") // type + .expression("([^,]+),") // type .expression("([AV]),") // validity .number("DATE:(dd)(dd)(dd),") // date (yyddmm) .number("TIME:(dd)(dd)(dd),") // time (hhmmss) @@ -56,14 +56,25 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + String type = parser.next(); + if (type.equals("CMD-KEY")) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } else if (type.startsWith("ALM-B")) { + if (Character.getNumericValue(type.charAt(5)) % 2 > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); + } else { + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); + } + } + position.setValid(parser.next().equals("A")); position.setTime(parser.nextDateTime()); diff --git a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java index bae187959..373858c79 100644 --- a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class GotopProtocolDecoderTest extends ProtocolTest { @@ -12,7 +13,18 @@ public class GotopProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "")); - + + verifyAttribute(decoder, text( + "867688033841044,ALM-B1-1,A,DATE:190622,TIME:144956,LAT:22.7193976N,LON:114.3878200E,Speed:000.1,100-22,03.72"), + Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); + + verifyAttribute(decoder, text( + "860264050778076,CMD-KEY,V,DATE:220516,TIME:090224,LAT:48.7592616N,LON:003.4658121W,Speed:000.0,057-21,01.60"), + Position.KEY_ALARM, Position.ALARM_SOS); + + verifyPosition(decoder, text( + "860264050778076,CMD-T,A,DATE:220516,TIME:100627,LAT:48.7636978N,LON:003.4652398W,Speed:051.4,077-24,01.00,WIFI:{84-a0-6e-94-42-5e&-47,b2-22-7a-56-5a-2a&-48,b4-b0-24-09-91-d4&-76,18-3c-b7-1f-da-67&-83,08-86-3b-94-78-44&-85,40-24-b2-c5-0f-5e&-87,b0-e5-ed-4e-06-61&-87,60-1d-9d-a6-d2-5d&-88,14-eb-b6-a5-55-8c&-88,40-18-b1-d7-28-54&-88},BLE:{1f-cf-4d-3c-61-bf&-91,39-82-d0-ba-34-69&-57,df-3a-31-ac-ad-72&-73,7c-d9-f4-11-0b-a0&-78,03-b5-9f-45-bd-0d&-88}")); + verifyNull(decoder, text( "353327020412763,CMD-X")); -- cgit v1.2.3 From 433816109a02622145ff5ead295d3aff5bafaacd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 17 May 2022 18:11:09 -0700 Subject: Decode Minifinder pet activity --- .../java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 10 +++++++++- .../org/traccar/protocol/Minifinder2ProtocolDecoderTest.java | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 641a45864..c63226c80 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 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. @@ -263,6 +263,14 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // timestamp position.set(Position.KEY_STEPS, buf.readUnsignedInt()); break; + case 0x31: + int i = 1; + while (buf.readerIndex() < endIndex) { + position.set("activity" + i + "Time", buf.readUnsignedInt()); + position.set("activity" + i, buf.readUnsignedInt()); + i += 1; + } + break; case 0x40: buf.readUnsignedIntLE(); // timestamp int heartRate = buf.readUnsignedByte(); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index ab23f277a..1813a5370 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { var decoder = new Minifinder2ProtocolDecoder(null); + verifyPositions(decoder, binary( + "AB103D0035A700000110013836373733303035333430333237390924AC5783620103C250162030CC5F0D5002FB432D00AF005A3158006D0A00000B0931EC5783620A000000")); + verifyPositions(decoder, binary( "ab10350015ae59010110013836333932313033333836353231360924723a12610042535a182ac0f6b4f2923100c900af02215c2b9bfb5461736b4c4d53")); -- cgit v1.2.3 From 68a1b67be1c7fe9b22805a8d4c1e7a4c7d0bf2ed Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 18 May 2022 18:36:43 -0700 Subject: Handle Ruptela identification --- .../java/org/traccar/protocol/RuptelaProtocolDecoder.java | 15 ++++++++++++++- .../org/traccar/protocol/RuptelaProtocolDecoderTest.java | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 2812d22ff..5a0383358 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -50,6 +50,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SMS_VIA_GPRS_RESPONSE = 7; public static final int MSG_SMS_VIA_GPRS = 8; public static final int MSG_DTCS = 9; + public static final int MSG_IDENTIFICATION = 15; public static final int MSG_SET_IO = 17; public static final int MSG_FILES = 37; public static final int MSG_EXTENDED_RECORDS = 68; @@ -306,6 +307,18 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { return null; + } else if (type == MSG_IDENTIFICATION) { + + ByteBuf content = Unpooled.buffer(); + content.writeByte(1); + ByteBuf response = RuptelaProtocolEncoder.encodeContent(type, content); + content.release(); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + + return null; + } else { return decodeCommandResponse(deviceSession, type, buf); diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java index 64ac6a57e..eca7518a7 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class RuptelaProtocolDecoderTest extends ProtocolTest { var decoder = new RuptelaProtocolDecoder(null); + verifyNull(decoder, binary( + "002e000316d53d58d6020f4573303430302e30332e36382e30340000c2b3090d0e950000827b000003e80000003c003c1681")); + verifyPositions(decoder, binary( "00800003167d765c155d01000160cd0a310000faae43f7176ee45702332b0c12000006070d05007300cfff260082008600870088000f00d7021100d801c900061d0000c500001e0e988300008900008b000002d0000c9bca720c889a0b047e00000000000000007f0000000000000000800000000000000000810000000000000000a341")); -- cgit v1.2.3 From 56f742c2e3e009c6af74fec689c459958d8945e7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 May 2022 15:45:57 -0700 Subject: Fix user creation --- src/main/java/org/traccar/database/UsersManager.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java index 31759dc8b..a54226cfe 100644 --- a/src/main/java/org/traccar/database/UsersManager.java +++ b/src/main/java/org/traccar/database/UsersManager.java @@ -59,6 +59,12 @@ public class UsersManager extends SimpleObjectManager { } } + @Override + public void addItem(User user) throws StorageException { + super.addItem(user); + getDataManager().updateUserPassword(user); + } + @Override public void updateItem(User user) throws StorageException { if (user.getHashedPassword() != null) { -- cgit v1.2.3 From 6c4294b9a3f59c9615be74c04d4c8e047ef3ff4f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 May 2022 11:00:14 -0700 Subject: Fix style issue --- src/main/java/org/traccar/storage/DatabaseStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index ff77ff8a8..388fd4016 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -319,7 +319,7 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(expandDevices? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) + result.append(expandDevices ? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From d2b164d54e4ae831b562ca7917d3117f2fe78c24 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 May 2022 13:26:22 -0700 Subject: Fix permission requests --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 4 ++-- src/main/java/org/traccar/storage/query/Condition.java | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 40d679ded..1c306630c 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -56,11 +56,11 @@ public class ExtendedObjectResource extends BaseObjectResou if (groupId > 0) { permissionsService.checkPermission(Group.class, getUserId(), groupId); - conditions.add(new Condition.Permission(Group.class, groupId, baseClass)); + conditions.add(new Condition.Permission(Group.class, groupId, baseClass).excludeGroups()); } if (deviceId > 0) { permissionsService.checkPermission(Device.class, getUserId(), deviceId); - conditions.add(new Condition.Permission(Device.class, deviceId, baseClass)); + conditions.add(new Condition.Permission(Device.class, deviceId, baseClass).excludeGroups()); } return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 91ede236c..4cfdc907f 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -165,10 +165,6 @@ public interface Condition { this(ownerClass, ownerId, propertyClass, 0, false); } - public Permission(Class ownerClass, Class propertyClass, long propertyId) { - this(ownerClass, 0, propertyClass, propertyId, false); - } - public Permission excludeGroups() { return new Permission(this.ownerClass, this.ownerId, this.propertyClass, this.propertyId, true); } -- cgit v1.2.3 From 402fd2b7faf1528f887de22d8175ccd80acf24a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 May 2022 13:34:16 -0700 Subject: Another permission optimization --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 1c306630c..6037118dd 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -47,11 +47,11 @@ public class ExtendedObjectResource extends BaseObjectResou permissionsService.checkAdmin(getUserId()); } else { if (userId == 0) { - userId = getUserId(); + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } else { permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass).excludeGroups()); } - conditions.add(new Condition.Permission(User.class, userId, baseClass)); } if (groupId > 0) { -- cgit v1.2.3 From 69d45b4429be70ce079b51200f6baefeb3873220 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 23 May 2022 18:22:42 -0700 Subject: Self access permission --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index c640f8d74..e7955086a 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -126,7 +126,7 @@ public class PermissionsService { public void checkPermission( Class clazz, long userId, long objectId) throws StorageException, SecurityException { - if (!getUser(userId).getAdministrator()) { + if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { var objects = storage.getObjects(clazz, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, clazz))); -- cgit v1.2.3 From fed6597faa141ba3ee8b11bff2c987ac981fd91b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 May 2022 08:59:27 -0700 Subject: Include address in login logs --- .../java/org/traccar/api/resource/SessionResource.java | 5 ++--- src/main/java/org/traccar/helper/LogAction.java | 17 ++++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 8422e0b49..136aab0eb 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -110,8 +110,7 @@ public class SessionResource extends BaseResource { @FormParam("email") String email, @FormParam("password") String password) throws StorageException { User user = Context.getPermissionsManager().login(email, password); if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } else { LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); @@ -121,7 +120,7 @@ public class SessionResource extends BaseResource { @DELETE public Response remove() { - LogAction.logout(getUserId()); + LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); request.getSession().removeAttribute(USER_ID_KEY); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/helper/LogAction.java b/src/main/java/org/traccar/helper/LogAction.java index d16b25483..b255b9206 100644 --- a/src/main/java/org/traccar/helper/LogAction.java +++ b/src/main/java/org/traccar/helper/LogAction.java @@ -47,7 +47,7 @@ public final class LogAction { private static final String PATTERN_OBJECT = "user: %d, action: %s, object: %s, id: %d"; private static final String PATTERN_LINK = "user: %d, action: %s, owner: %s, id: %d, property: %s, id: %d"; - private static final String PATTERN_LOGIN = "user: %d, action: %s"; + private static final String PATTERN_LOGIN = "user: %d, action: %s, from: %s"; private static final String PATTERN_LOGIN_FAILED = "login failed from: %s"; private static final String PATTERN_DEVICE_ACCUMULATORS = "user: %d, action: %s, deviceId: %d"; private static final String PATTERN_REPORT = "user: %d, report: %s, from: %s, to: %s, devices: %s, groups: %s"; @@ -72,12 +72,12 @@ public final class LogAction { logLinkAction(ACTION_UNLINK, userId, owner, ownerId, property, propertyId); } - public static void login(long userId) { - logLoginAction(ACTION_LOGIN, userId); + public static void login(long userId, String remoteAddress) { + logLoginAction(ACTION_LOGIN, userId, remoteAddress); } - public static void logout(long userId) { - logLoginAction(ACTION_LOGOUT, userId); + public static void logout(long userId, String remoteAddress) { + logLoginAction(ACTION_LOGOUT, userId, remoteAddress); } public static void failedLogin(String remoteAddress) { @@ -105,8 +105,11 @@ public final class LogAction { Introspector.decapitalize(property.getSimpleName()), propertyId)); } - private static void logLoginAction(String action, long userId) { - LOGGER.info(String.format(PATTERN_LOGIN, userId, action)); + private static void logLoginAction(String action, long userId, String remoteAddress) { + if (remoteAddress == null || remoteAddress.isEmpty()) { + remoteAddress = "unknown"; + } + LOGGER.info(String.format(PATTERN_LOGIN, userId, action, remoteAddress)); } public static void logReport( -- cgit v1.2.3 From 0ba89aa35180f965e8c8ca85560d7ee7a1849b3c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 May 2022 09:02:56 -0700 Subject: Fix login issue --- src/main/java/org/traccar/api/resource/SessionResource.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 136aab0eb..1ccba1270 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -110,6 +110,7 @@ public class SessionResource extends BaseResource { @FormParam("email") String email, @FormParam("password") String password) throws StorageException { User user = Context.getPermissionsManager().login(email, password); if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } else { -- cgit v1.2.3 From 284de955abc4526fd988f350666558f57db1507f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 May 2022 17:02:52 -0700 Subject: Decode A1L808 lock info --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 13 ++++++++++++- .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index c280ee9b2..9f54c8486 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -493,7 +493,18 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; case 0xD5: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + if (length == 2) { + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + } else { + int count = buf.readUnsignedByte(); + for (int i = 1; i <= count; i++) { + position.set("lock" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(5))); + position.set("lock" + i + "Card", ByteBufUtil.hexDump(buf.readSlice(5))); + position.set("lock" + i + "Battery", buf.readUnsignedByte()); + int status = buf.readUnsignedShort(); + position.set("lock" + i + "Locked", !BitUtil.check(status, 5)); + } + } break; case 0xDA: buf.readUnsignedShort(); // string cut count diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index d61dae315..c45effbc5 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); + verifyAttribute(decoder, binary( + "7E02000053200002604323004800000000000C00000158B91406CB7007006B00000000220512101138010400000F2803020000250400000000300114310100E30100D50E0100026043232795980277530030E50400000000E7020FC8E8020E83AB7E"), + "lock1Locked", false); + verifyPosition(decoder, binary( "7E0900005A4E5DE66FBA2200C4F02204280610090002010D052B0150052C0400129009052D016B052E014F05300231BA053502000005360203B8053802000005390200AD053D0201EA05440150054604009899D90545040000001E000C00030160A85C06D1C1389C7E")); -- cgit v1.2.3 From 8e8a435cea0ea44dfcb20b45dcbb881b87361676 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 25 May 2022 07:14:36 -0700 Subject: Avoid using MySQL keywords --- src/main/java/org/traccar/storage/DatabaseStorage.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 388fd4016..e8966be8e 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -319,7 +319,7 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(expandDevices ? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) + result.append(expandDevices ? "devices." : "all_groups."); // TODO handle reverse (e.g. users by device) result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); @@ -339,16 +339,16 @@ public class DatabaseStorage extends Storage { result.append(getStorageName(Group.class)); result.append(" AS g1 ON g2.id = g1.groupid"); result.append(" WHERE g2.groupid IS NOT NULL"); - result.append(") AS groups ON "); + result.append(") AS all_groups ON "); result.append(groupStorageName); - result.append(".groupid = groups.parentid"); + result.append(".groupid = all_groups.parentid"); if (expandDevices) { result.append(" INNER JOIN ("); result.append("SELECT groupid as parentid, id as deviceid FROM "); result.append(getStorageName(Device.class)); result.append(" WHERE groupid IS NOT NULL"); - result.append(") AS devices ON groups.groupid = devices.parentid"); + result.append(") AS devices ON all_groups.groupid = devices.parentid"); } result.append(" WHERE "); -- cgit v1.2.3 From 79b5d08f45e8be4ff7d0072cd91fed39d5afe117 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 16:46:35 -0700 Subject: Fix null server --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index e7955086a..4d5cd88ab 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -68,7 +68,7 @@ public class PermissionsService { public void checkReports(long userId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() - && (server.getDisableReports() || getUser(userId).getDisableReports())) { + && (getServer().getDisableReports() || getUser(userId).getDisableReports())) { throw new SecurityException("Reports are disabled"); } } -- cgit v1.2.3 From 8ed7d6cd19f221c40e9994c0469009ff9c0e46b1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 17:27:10 -0700 Subject: Fix several manager issues --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 4 +++- src/main/java/org/traccar/api/SimpleObjectResource.java | 4 +++- .../java/org/traccar/api/security/PermissionsService.java | 12 +++++++++--- src/main/java/org/traccar/storage/DatabaseStorage.java | 6 +++++- 4 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 6037118dd..e49f67bb9 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -44,7 +44,9 @@ public class ExtendedObjectResource extends BaseObjectResou var conditions = new LinkedList(); if (all) { - permissionsService.checkAdmin(getUserId()); + if (!permissionsService.isAdmin(getUserId())) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } } else { if (userId == 0) { conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index c61101077..15a496c5f 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -41,7 +41,9 @@ public class SimpleObjectResource extends BaseObjectResourc var conditions = new LinkedList(); if (all) { - permissionsService.checkAdmin(getUserId()); + if (!permissionsService.isAdmin(getUserId())) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } } else { if (userId == 0) { userId = getUserId(); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 4d5cd88ab..ac687fc1c 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -21,6 +21,7 @@ import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.GroupedModel; +import org.traccar.model.ManagedUser; import org.traccar.model.ScheduledModel; import org.traccar.model.Server; import org.traccar.model.User; @@ -60,9 +61,13 @@ public class PermissionsService { return user; } + public boolean isAdmin(long userId) throws StorageException { + return getUser(userId).getAdministrator(); + } + public void checkAdmin(long userId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { - throw new SecurityException("Account is readonly"); + throw new SecurityException("Administrator access required"); } } @@ -118,7 +123,7 @@ public class PermissionsService { public void checkUser(long userId, long managedUserId) throws StorageException, SecurityException { if (userId != managedUserId && !getUser(userId).getAdministrator()) { if (!getUser(userId).getManager() - || storage.getPermissions(User.class, userId, User.class, managedUserId).isEmpty()) { + || storage.getPermissions(User.class, userId, ManagedUser.class, managedUserId).isEmpty()) { throw new SecurityException("User access denied"); } } @@ -129,7 +134,8 @@ public class PermissionsService { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { var objects = storage.getObjects(clazz, new Request( new Columns.Include("id"), - new Condition.Permission(User.class, userId, clazz))); + new Condition.Permission( + User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz))); boolean found = false; for (var object : objects) { if (object.getId() == objectId) { diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index e8966be8e..cd82448e1 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -128,9 +128,13 @@ public class DatabaseStorage extends Storage { conditions.add(new Condition.Equals( Permission.getKey(propertyClass), Permission.getKey(propertyClass), propertyId)); } - query.append(formatCondition(Condition.merge(conditions))); + Condition combinedCondition = Condition.merge(conditions); + query.append(formatCondition(combinedCondition)); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + for (Map.Entry variable : getConditionVariables(combinedCondition).entrySet()) { + builder.setValue(variable.getKey(), variable.getValue()); + } return builder.executePermissionsQuery(); } catch (SQLException e) { throw new StorageException(e); -- cgit v1.2.3 From 950a35723b8ad3e9383c55d8b84812d012da3085 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 17:41:16 -0700 Subject: Fix wrong user permissions (fix #4853) --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index e49f67bb9..41ed3e9d9 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -52,7 +52,7 @@ public class ExtendedObjectResource extends BaseObjectResou conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } else { permissionsService.checkUser(getUserId(), userId); - conditions.add(new Condition.Permission(User.class, getUserId(), baseClass).excludeGroups()); + conditions.add(new Condition.Permission(User.class, userId, baseClass).excludeGroups()); } } -- cgit v1.2.3 From bb50a4178d171d40734b94fccf52b72733f1f04c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 19:28:31 -0700 Subject: Watch zero cell towers --- .../org/traccar/protocol/WatchProtocolDecoder.java | 24 ++++++++++++---------- .../traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 4ab7875b7..b25a15f93 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -145,17 +145,19 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int cellCount = Integer.parseInt(values[index++]); index += 1; // timing advance - int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - - for (int i = 0; i < cellCount; i++) { - int lac = Integer.parseInt(values[index++]); - int cid = Integer.parseInt(values[index++]); - String rssi = values[index++]; - if (!rssi.isEmpty()) { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); - } else { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + if (cellCount > 0) { + int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + + for (int i = 0; i < cellCount; i++) { + int lac = Integer.parseInt(values[index++]); + int cid = Integer.parseInt(values[index++]); + String rssi = values[index++]; + if (!rssi.isEmpty()) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); + } else { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + } } } diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 4fab19f26..34ef7839b 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -15,6 +15,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = new WatchProtocolDecoder(null); + verifyPosition(decoder, buffer( + "[3G*9031853319*004E*UD2,220322,055105,A,22.761162,N,114.360192,E,0,0,47,14,100,64,0,0,00000008,0,0]")); + verifyAttribute(decoder, buffer( "[3G*2104326058*000E*btemp2,1,35.29]"), Position.PREFIX_TEMP + 1, 35.29); -- cgit v1.2.3 From 56af285413c2337079332f303f7d091d65f09c4e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 28 May 2022 06:31:55 -0700 Subject: Decode G6W audio format --- src/main/java/org/traccar/helper/BufferUtil.java | 12 +++++++ .../org/traccar/protocol/WatchProtocolDecoder.java | 39 +++++++++++++++++----- .../traccar/protocol/WatchProtocolDecoderTest.java | 3 ++ 3 files changed, 46 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index 9485c17c6..1e1a687fa 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -27,6 +27,18 @@ public final class BufferUtil { private BufferUtil() { } + public static int indexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value, int count) { + int startIndex = fromIndex; + for (int i = 0; i < count; i++) { + int result = buffer.indexOf(startIndex, toIndex, value); + if (result < 0 || i == count - 1) { + return result; + } + startIndex = result + 1; + } + return -1; + } + public static int indexOf(String needle, ByteBuf haystack) { return indexOf(needle, haystack, haystack.readerIndex(), haystack.writerIndex()); } diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index b25a15f93..420866578 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 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,14 +18,13 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.BufferUtil; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -41,7 +40,7 @@ import java.util.regex.Pattern; public class WatchProtocolDecoder extends BaseProtocolDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(WatchProtocolDecoder.class); + private ByteBuf audio; public WatchProtocolDecoder(Protocol protocol) { super(protocol); @@ -318,13 +317,37 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type.equals("JXTK")) { + + int dataIndex = BufferUtil.indexOf(buf, buf.readerIndex(), buf.writerIndex(), (byte) ',', 4) + 1; + String[] values = buf.readCharSequence( + dataIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString().split(","); + + int current = Integer.parseInt(values[2]); + int total = Integer.parseInt(values[3]); + + if (audio == null) { + audio = Unpooled.buffer(); + } + audio.writeBytes(buf); + + sendResponse(channel, id, index, "JXTKR,1"); + + if (current < total) { + return null; + } else { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, null); + position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, audio, "amr")); + audio.release(); + audio = null; + return position; + } + } else if (type.equals("TK")) { if (buf.readableBytes() == 1) { - byte result = buf.readByte(); - if (result != '1') { - LOGGER.warn(type + "," + result); - } return null; } diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 34ef7839b..ef6c33da9 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -15,6 +15,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = new WatchProtocolDecoder(null); + verifyNull(decoder, binary( + "5b5a4a2a3738393436383035303034323639322a303033342a303433392a4a58544b2c302c77617463685f375f32303232303532363039333935342c312c362c2321414d520a0c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c389814ffcd762fe49d50ae7a2e0cb528aefbf76911df05c2fbe17d050c2200cff77ef0df4d9b4ab9a4340c449814dbe7c63fa82bc3750d800cc48abbffddb0df8e8fda95e5980c49982ff6cf65f9377d02a39c3aaa0c389805f2ff42c1b80e0a0eb1dc0c2998e9defe15cfa3bdbe80d3540c7298c2f6d9239e3eae3c4a81660c490034dbfd513fedad0c2fc3900cc40039b7f71bb0657ba75558c40cd7813b97ff7219777ec7f401260c7d040003bff6f75fdb898a6ba1140cecd127f7f83357cb73a68a5f680cb081d4f6e749e6af8ed367bc480cec1815dfffd2dbed358112af320ccc21179fffbd17a3a61c133b380c920047defc72a784770ec0fe400c383c42f6faebe76fa736e9d1be0c4918e7decddc67ec9afd87ff220cc418e6bffe6cf6c9ac1f83c3900ca6cad1ffe3da24e1be3b547d03c00c6b00b8fee77f60a76d3e7d0292e20c2918b7bfff76387b793d3a36300c7d0400b7fff7f63ae513ac6f74de0c980016fbff7d01f9b30fca67c7220caa982ff6dbd7bf3d8dfed143ec0c44982fdfcb7b517e26f6ea52420c0ed19cfedb438f179d3fc50ec40c008ad2ffff635fe28dc1ec1f860c76cb7d05bffda53eaebe4d201ae20ccccaffbbfd3db4abb6ddf39d0e0c6b00acfeff406fe4a12661caf80c76982fbffffeb17b2f65472f300c7d04c24bf6ef1b10e47f73fc10b40c76036cfecd4e7837145a6a8e900ccccaf2beeba36fbaa36feb60640c7d0400dfffff73bfa3b87d0256a1700c7d04e4efd6efc23b651eb73e77780ccc1813ffffb39f6baa6f3195080c00007afffee0b9df6346ca08d00c6bca7d04feff4d64a7b56f9855da0c769819fbfd954ea5bd7d040ba6420c4c4c09bfffd5f6c57d01930e7d01220cc48a22dffe30bfcbaf08a795140c7d040433b7ff3cba5f3e336a40060cecbd2bfaf775bea7bde7e095ee0cc4caaef7fb623feeaab69eabc20c8c0021bffd1ea4a1b090175a920c7d046445fbdfc1abe910b0ca56160c7d0440cbd7ef03893c7f7d02e1a8c20c85e42dff5fdaa145759d326b5a0ccc4084f75f8eeb7b15e4eb4ff80c6bc22ef7d7eaf8df3b8ff678cc0cca4026f3cf7518fd731ceca3560cec041ffbe7655eaf822f04c4fe0c7d0478e3fbfcb5dfc8a81fdbb9e20cc418e6d7ff777f26affe37cc020cd7977cbff7d0aecb9727be6a0c0c00bde1f2d797fc8754ed09d4ae0cc498279f7e729fcb9eff70c1a60c7d0478e5bfffc67eef953fda69aa0c7200f1bbf7e891ef5a287cb5b80c983629fee5555f739f8a29279a0c76d103bef73f55a6bf89ba8ce40cc46424f6ded9a194167a067d05880cc4780efeffc37fae944d89bfb40c4464bffffb6dd54e8344394a5c0c49781ffffc653feaa31af59ac00cc464cebfd76ae4e8a55d5b5a4a2a3738393436383035303034323639322a303033352a303434332a4a58544b2c302c77617463685f375f32303232303532363039333935342c322c362c5f24fbbc0c7d04983effcfe35fbd8fff7ce6f60c448a1dfbd715bec3b42448e58a0c0e0421bf5f17ebc31a43301bc40c768ababf4f66cf629ee31fe9900c6b6426bf5f4eb7669dacc439140c945733bff9351e7d04ab6be54ef60ccc98bfbffbf67f63b78d8f42880c7d0400c6f7fffab5cbae8e8275da0c0097ffdefff5dfafb0c4727d04980ccc78d1f6ff1a6b7e37631059fa0c760045f3fd853fea877d03aa87440cc40022f7ffa8b5c58f6e80c58e0ccc4c1f9ffff32fa7af87de04560cb09801f6fdd32efcbdad9495b60c6b987d05bff72d61eb687d05a9f9e20cca57c7ffff6cb1fe3387ea596e0c629823dedfbfc50b97965e44ea0c4918ccbfd7cc75e59fff92e9ee0c8c78e7faff707ffda60ec3ada60c30c217befffcb8f3290f06d75e0c0e8a7bb7dff3eec7b7928ef6680c38ca1cdeff272ba012597d051a520c0018dfffeff27d01e369b3bcd7d80c98146eb2fc7f45c38e1ce53e120c3d5700ff7fd44bee28aa089d900c007157bffffe30302d7d0583585c0ccc5747bfe7f73cff7d02de1098240c7d047865f6feca71d70bdfaab6a20cecb946bfd966be74b61a06c6660c441612ffe7eb966a8c2886cf760ccc7827bffd653ff7980a62e9320c00ca98f7fc1b311a3986700cc20c490017bfff70cfe7bb455637320c6228afbf7e6da4c59763b693740cccc2b5fee1951975760e4a9dca0c0000faffdb255f6f86af4be6fc0cccc2ffdfff7d0225efbc847c42760cb48a8fdffbe23ff1a78782cbe60c7d04980cffff6e6dfc75a6c65a500ce62808bfff24f853748a9537400cb4004ebfeb6e70aa4314903e8c0cb46408ff72d62f44945f64897d040cccca7abfff2db5c6bfcc345e700c7d04c24dd6fd5f95638f78974a800cc4caffffffb17d01c36bdd7d047c2e0c7d0436d1f7f8917f83af7fc5c2180c070449f6fe570f128577c8c97d040c7d047813f6df3fd17d026b6790d1b80cc400c9d6d92dc56497843ed10a0c44986effffe13fef8eef7c717a0c7d049872bbfdad3abe2be0d60b240c4900adbf7d02dfa4ef960fdf23580c629845fefc5a650fbf8b0d4cda0c7d040076b7ef273fe78fce983ae40c4a00ded7ff629f7fab4531501c0c6200b7ffedf13fe6a68f01fb6c0cc49809f77fdb91517fb39e8ba00c760009bf7fd6afe7b46921f27a0cecbd1df6faf99120776e807d03fe0c98ca23fbff3749fb5ed3909c160cc44cbbbfffbd70e77d0367bc2e740c499816f77fe2ffe08edd7d048c9e0c940021beff1df0f1338c2f1a3a0c7d040083feebba1c756e5760c2200c94981dfffdf921b92b99909ba40c7d04984ebbdf7ff0c77d025a1fbfc00c7657b3ff77f4befcae2bf625640c62ca53f7fdb35f2e92af3bd5c60c7d049878bbdfc0dfc1bdaa1918000cc404bbbfefb41ee6b50a39bf180c767874f7fb8ee156320ee600020c69981cffffe0fff6bb2764acaa0cec781bfbff7d0324eb9b4b4d5d5b5a4a2a3738393436383035303034323639322a303033362a303433302a4a58544b2c302c77617463685f375f32303232303532363039333935342c332c362c73580c07ca4fbbfff5bec5abcfac465c0c0042a8beff316aed38fe4603dc0c7d04577d04fefdc929f7294ce7520c0c76984dfaff402fe68ebe113b000c7d0436a6fed465ff4f8d8e3306300c44e434f7f79e84abb8fa081be80c983636bef7e128bf7d03d34c71c80cd7982dffd54cac94536beab1320c058bd6bfff701fe69d1a39d1e80c76caedb77ffea0e47febb469440c0098b2bef5e55eed981672b1c40cd800d1bef4bda58daf7d01d309180c08cadffbfc31799f5613fab2da0c7d049828beffa5eea0bd09a14c2e0c0000e59feb5f9dff7f4945e98e0cc40046ffcfe57fb58f7d053dd9e20c7d040047d7ffd38f67aa9db8d38c0c7698d2df5fe2efc6bb0f5a18220c980367bbfd95dae73e3bf2b59a0c49813796fdf5efab9d3ed7d3d80c9800ebd7fdb831ae8f91811e920c7d04ca74bbff5cdcf45605c25f140c013e029fbfe7ffc299376b409a0c7510009e7d02010f68824cccead60cb13b00f7d5821e6c8d594a06880c75ec00f6e782e8f06b0c610d1a0cc09843dfef117fa5b3aef236f40cdcc208ffff4831f83703ca20c00cc09800bf7fd71eec9ba34e3c200c650f6bffd5bc4dbe7ec5b0f1d80c0d1c1f92ef917fa0b96023eac00c8efb1db6bfa42eed9f69051d4e0c8eff23b2fe4486d56ef44f702e0c8ebc1b9657d46eeea852ac337e0c8efb1f96d9877fc9b34c38f1540c121c2796df13577c727f8cedec0ca9107d05afdd6a9d957ab76c02560c121c2dd6bfd33fa5b844f27d02340cb11037b6e3962e6eaf52d6e7460c2b1c3db2dfe61eef9aad3dcc0a0c542e42d763e709fe723a83ae7c0c7cfa56bf7fedb8763c3f8ab2c00ca40022efff2411604d22a485e00c228adcbfdfcd748293c66b0bf20cb10f0097ff806dcf7a0a640d6e0c5a0400b7e3030ef4ae0a6046f80cb82812fe7b04d77e4bab11894a0c541c24b2dd53fea5891e3824420ca9fb26b2d7156fa485049cac420ca91c2d9edb2487526c2e2260fa0ca9bc25b65ff28e41a34232c0f00c8efb25b649e51ec39c0ae6703a0c70f425a6c820dfaf2f8124c8960c80f42794b323aed9ca9b6924be0cb93b278e3e8d929c36bb70b6360c587b27524f85857d056d214841660cda2f278b4c876eb3186e5acc540ce6832f6e3f0d82f81226e6dc3a0c0b922feff50a03d03c98ae28360c03d62befb54ab611de0c8addee0c84d626b7fdb4461556dc0153040c0b0f27ff5781c5c2b32f6762140c49bf2dfaf521969b702ecb11d80c7d050f27cfed75bfab95dc4af3180c011c3d8e7451df80a5cd0948080c7c2e35f2c7b0becca22e50769e0c7c1c3d965e628f46a9a58ae6100c7c2e3b965f4a6b5ebd1436b0b00c7c863eaedf18c7816cdeeed7e20c2b3e3df6b73952b2b1abc048a00c7cfb3db6cd67ae68cda18af9d60c2bff3e96df12ff61b39627cd580c7c863fd6cd810ee595d85ee6645d5b5a4a2a3738393436383035303034323639322a303033372a303433372a4a58544b2c302c77617463685f375f32303232303532363039333935342c342c362c0c7cff3fb65f812fe196dc62d8360c7c2e3db2de738fae9ca7c7236c0c2b2e3d96df6c1d775a3df5a47e0c7c3e3f96fe943dc07e81e170700c75503fb7d6a6197f1b08df85440c5a133ab6d6a0e68f3acb04b7b00cfa293fd6cfc20c390d5265d3c80c581347b278077d03dc22d9e49c680ce64d47924e8dcdffe9be19dc100cb90f4f9e612d2201961c2e111c0c003b4febb58a96c809ab5a71040ce6d759fbddba54b2aa9d9d983e0cc029576ecf1f703099d84994520c4029579e7d0281577073f5629dd80c5a2952b6fed177177d01e57d0175c20cd8647d044f7e3c58aba523ddb0720cb56753d3e9c6799f95938401f60c756414ff5f00fb57bc4d7e111c0c7c085573ef743ee19ca30057e00c752e5ab77e34eec69f3cbe53940c542e4d96d6e7ff03854a9506620c7cff55b6efca197610a86606180c7cfb55b67eb25f4b999c002bf20c7c107d03beeb451fad8d042492740cb8f05eb5ff664f679c1cc991c60ce1671bffd33d9445b57d0584c7d60c07781dfef5e3ee81b45ff8a8c80cc40072b7dfe6fe6e978257253a0cb1131fe6783035868e439b00d80c583b27b17ecb53dd165c3422180c703b2fbeb18d023e14d90304700c3cce2b93cdc2e6b3550a5546160cb13b3b72fe24273859059b52040c224d34edc742f6bb7c877d02b5940cb84d37cdcfcbc3f03a041cf4ac0ca4923a9f3b74e805b235cce8660c759000fbfd90565072aa7d03bb520cb592017f411dcbe80a0cc420360c09d6528fcf2e25b382ee46d75a0ce2e853d3cfb617fd7d023f05e0780c07cc3bbabfa9f6cec5aa48ac600c404208fb678a4cf16a9c09098c0cf14244fbdfc2afe7932fe57d02900c011c369e7d0264a8570a54f9a2e80cb1103daed6249fe59dc888c2ac0cb1103573c5f697be759923ecc80c705f7d059effaaa4b09b976f375a0c804223bbed89767d041693edab180cb49819d7eb5a8573bb10c951540c3c643af74f021f25b6dd3b7d02040c07982bd73fb31fe38f09a227a40c037610ff7d03c6058098fef936a80c03b808debbe055a1a71319128c0c6b8f2e9e3bb52d71c226d3141a0cdab82d7fa9d416167a1cb950020c03c32bb23ee9e3743f3b6853060cc02937adb5157d05f4a6960c1b680c4076365e6b754bda9394a7aa720c06293ef23313fb1b94bcc2c09a0ce676006bbd8e0417941b90d23c0cb9294f7d01fd3d65748cf6d1cc220c03767d035e3a65e6f2514ab1db060ce6d965bf4035f65c79a9e4446a0ce62921dbf46457b56cd65f6c500c584d6bba7ea8166edd6cf7693a0cb939227bfca25f82a7c4202f2e0c06ce2b9a4f0d95f39eb43c22840c06901eef6fd15fe48f452000e00c62023afbffb269beba0ee0ac540ce6ec00f37b8139f2026e80f1440c22501dfe7d017d03ed8c3ff6803f240cc48ae3b7fd725e63a347cd64100c0094f8efdeb0a9f35c83eb06b00c005d5b5a4a2a3738393436383035303034323639322a303033382a303433332a4a58544b2c302c77617463685f375f32303232303532363039333935342c352c362c6647deef2df57fb68fd76b660c44e43cbfefc0beec867d025c3f920cb4507d01ff6f42ee6c1f58a0db0e0c7d045701ff7f19f9f90fdff037c20c4404259efcd47d02a52b7ef6df0e0c7d04d128f3578db14779993109560ce1e41ecffd2851af49256b1ecc0c7d049837ffff707168db3dd1ac240cc09419f7f39a7d013d6ec1b4e55c0cc4881cff5f49f55fadc52285a40c06ce9ad7dbb8349b97031ac3b00c407d049d9bed74dfadad950eab560c06799ffac7a924b18bdf11c3d40c8054a2f777522e65be921a77240c8042a19bff706fe5b7e3e7d0360cd82840bff3f4fe429bea0081560c0064419fd9157f8b9c797e92c20cc47fe2b7d5e6ee45bf0524010e0c0894299e7d037e4553bcbbc0989e0c40501bbbdc926f8daf53885e0a0c80971ffee559f5bf98ed54cf140c00581abbffac75b88b14d5e3780c5a046dd66fd7bfe5b7ca749df40c403672bbcfe47ee797860ded5e0cb5502efb7ee2ffc7bbdc27d0880c44ca08fbf7031ecd9321d21ef40cdc9806fefde36f0699ad1569420c22cb1bfbdc974fcb900ab601440c00cb1cfbdfd2f7d2730b0b46680c0b4203dfef309fe0adc121e2080c225829feeb901f25b926343bae0c624204dfff4875b69ceda4df4c0c499886ffe7301e8e8bf9ef0a260cdce408dbef829fe45337e98d860c010800ef76088d8015f3b2c84e0c755c3ecfc898f50fbcdb9344220c7c7d03459349337d01e4949da1b4ec0c7cf046ae6e4a90df3552070a5e0c7cf045d23fbba0951147986eca0c7536426e6ef2ef0b7d01c22fd2960cb8284e9db92d40552988334f200cb8024acdbfea90d13b545fe35e0cb8f04d5e48659d48b97c1096140c7c084f79df4402702126bf358a0cb8a74d4def66535e145638d12e0c543e4d8edfa2531b15a340eb800cb83e4eafbd9031291a8563e4780c54a74ef1c7300da79aa94bb67d050cb8f04eba6fb0325813871511b80ce20ff6fffd404ed58ecf264c8e0c7c0f1cb3fe1a36fb7187c379d00c7c3e52f6727d0261ca8bdd1361b80cb8d64d9a4fb1cfe0aadaaa7d05c40c2b2e44b2bfb9b4dcad9d7d0200280c7c3b47d5db803fc2aee71a77f00c7c1343b2bfa06ee6ad3228f10a0c7c3b4a76477fe7650b0c809ca80c54d74b92dbc327134514d6126e0c7c5f4a8f4f74efaaa5cd0a43bc0c7c104bb64ff5ce604fa2028b680c7cff4aaec7f7a9394cc4c599e60cb8ce52eeb553d215a6a466b4120c750f4fae5f9816c04a0a3f751e0c75e04f73c58e96bb4b925a4c680cb80f4b6e3fe1635614bbdeccbc0c7c3b4faf7e825e42d473ee76800ce298578ffcb61f0af936387bbe0cb800e39bf62410681583e0d2b20cb4987d05ff7f297bf69eaf4cd8b40cb57815bf7f300fcffe9fae966a0cb497acd75fd37f648d00d141a00cc48af9fffe1a3b979b8f8573e80c29bff1bf4b94c6fd7c3eec075e0c7cce1f5d5b5a4a2a3738393436383035303034323639322a303033392a303065352a4a58544b2c302c77617463685f375f32303232303532363039333935342c362c362c8f5cf9f34fa6edceb18c0ca4ce436e7d02d329de94b63eb11a0cb894438f44cf753dbc1a83b4560cb8e44391eff729d4155a231bf40cb59443f373b4288492cd6e38160c5a42049bfec8678ad42bce0c560cb12e39fec3d1fe24b5572ee0be0cb1ce35fe33688455aa74e3ffa40cb1d635df4b704160ae864a7d03440cb10f3267dbf4a21d540ca1051c0cb11337724f8747f5547d054e91660cb1a73692df964f3bbb0758d41a0cfe05b60c314460297eae4185f20cad673ceb6dfa05ddbe0278d5de5d")); + verifyPosition(decoder, buffer( "[3G*9031853319*004E*UD2,220322,055105,A,22.761162,N,114.360192,E,0,0,47,14,100,64,0,0,00000008,0,0]")); -- cgit v1.2.3 From bcd8d095de5e5b99dec3420ddd91419a0a3ba238 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 28 May 2022 11:29:12 -0700 Subject: Fix duplicated report devices --- src/main/java/org/traccar/reports/ReportUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index 58674beae..23646c4d6 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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"); @@ -48,6 +48,7 @@ import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -83,7 +84,7 @@ public final class ReportUtils { } public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { - Collection result = new ArrayList<>(deviceIds); + Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); } -- cgit v1.2.3 From b9d7cbe6f15b471b0edff49870fef8190949ad09 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 28 May 2022 11:29:34 -0700 Subject: Ignore empty summary records --- src/main/java/org/traccar/reports/Summary.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index 4924af062..f00b1ca57 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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"); @@ -127,7 +127,12 @@ public final class Summary { ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(calculateSummaryResults(userId, deviceId, from, to, daily)); + Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (SummaryReport summaryReport : deviceResults) { + if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { + result.add(summaryReport); + } + } } return result; } -- cgit v1.2.3 From b1a971eedb18a11af2cdc70ba5f8004bae89defd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 11:16:05 -0700 Subject: Remove unused interface --- .../java/org/traccar/database/DeviceManager.java | 4 +--- .../java/org/traccar/database/GroupsManager.java | 20 +--------------- .../org/traccar/database/ManagableObjects.java | 27 ---------------------- .../org/traccar/database/SimpleObjectManager.java | 5 +--- 4 files changed, 3 insertions(+), 53 deletions(-) delete mode 100644 src/main/java/org/traccar/database/ManagableObjects.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index a9b8454eb..a14fd7022 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -38,7 +38,7 @@ import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.storage.StorageException; -public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { +public class DeviceManager extends BaseObjectManager implements IdentityManager { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); @@ -162,7 +162,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return Context.getPermissionsManager().getDevicePermissions(userId); } - @Override public Set getUserItems(long userId) { if (Context.getPermissionsManager() != null) { Set result = new HashSet<>(); @@ -186,7 +185,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result; } - @Override public Set getManagedItems(long userId) { Set result = new HashSet<>(getUserItems(userId)); for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java index dafddc0cc..9322dd80a 100644 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ b/src/main/java/org/traccar/database/GroupsManager.java @@ -23,7 +23,7 @@ import org.traccar.Context; import org.traccar.model.Group; import org.traccar.storage.StorageException; -public class GroupsManager extends BaseObjectManager implements ManagableObjects { +public class GroupsManager extends BaseObjectManager { public GroupsManager(DataManager dataManager) { super(dataManager, Group.class); @@ -62,22 +62,4 @@ public class GroupsManager extends BaseObjectManager implements Managable super.updateItem(group); } - @Override - public Set getUserItems(long userId) { - if (Context.getPermissionsManager() != null) { - return Context.getPermissionsManager().getGroupPermissions(userId); - } else { - return new HashSet<>(); - } - } - - @Override - public Set getManagedItems(long userId) { - Set result = getUserItems(userId); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - } diff --git a/src/main/java/org/traccar/database/ManagableObjects.java b/src/main/java/org/traccar/database/ManagableObjects.java deleted file mode 100644 index ec9549493..000000000 --- a/src/main/java/org/traccar/database/ManagableObjects.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.database; - -import java.util.Set; - -public interface ManagableObjects { - - Set getUserItems(long userId); - - Set getManagedItems(long userId); - -} diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java index 78701720f..74bbc054f 100644 --- a/src/main/java/org/traccar/database/SimpleObjectManager.java +++ b/src/main/java/org/traccar/database/SimpleObjectManager.java @@ -29,8 +29,7 @@ import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; -public abstract class SimpleObjectManager extends BaseObjectManager - implements ManagableObjects { +public abstract class SimpleObjectManager extends BaseObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleObjectManager.class); @@ -40,7 +39,6 @@ public abstract class SimpleObjectManager extends BaseObjec super(dataManager, baseClass); } - @Override public final Set getUserItems(long userId) { try { readLock(); @@ -55,7 +53,6 @@ public abstract class SimpleObjectManager extends BaseObjec } } - @Override public Set getManagedItems(long userId) { Set result = getUserItems(userId); for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { -- cgit v1.2.3 From 154ff3b2175e67b3fac531cb9c5c5c68880f5e12 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 11:49:39 -0700 Subject: Inject media manager --- build.gradle | 1 + src/main/java/org/traccar/BasePipelineFactory.java | 9 ++++---- src/main/java/org/traccar/BaseProtocolDecoder.java | 14 +++++++++++ src/main/java/org/traccar/Context.java | 12 +--------- src/main/java/org/traccar/MainEventHandler.java | 2 ++ .../java/org/traccar/database/GroupsManager.java | 3 +-- .../java/org/traccar/database/MediaManager.java | 12 ++++++---- .../traccar/protocol/AtrackProtocolDecoder.java | 2 +- .../traccar/protocol/DualcamProtocolDecoder.java | 3 +-- .../traccar/protocol/FifotrackProtocolDecoder.java | 3 +-- .../traccar/protocol/GalileoProtocolDecoder.java | 2 +- .../traccar/protocol/Gps103ProtocolDecoder.java | 3 +-- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 6 ++--- .../traccar/protocol/MeiligaoProtocolDecoder.java | 2 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 2 +- .../traccar/protocol/RuptelaProtocolDecoder.java | 3 +-- .../traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- .../org/traccar/protocol/WatchProtocolDecoder.java | 7 +++--- src/test/java/org/traccar/BaseTest.java | 27 +--------------------- .../traccar/protocol/WatchProtocolDecoderTest.java | 18 +++++++-------- 21 files changed, 57 insertions(+), 78 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 25c8a32e3..de8c86712 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" testImplementation "junit:junit:4.13.2" + testImplementation "org.mockito:mockito-core:3.+" } task copyDependencies(type: Copy) { diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 89ef76a80..1f383f211 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -109,7 +109,9 @@ public abstract class BasePipelineFactory extends ChannelInitializer { pipeline.addLast(new StandardLoggingHandler(protocol)); addProtocolHandlers(handler -> { - if (!(handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder)) { + if (handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder) { + Main.getInjector().injectMembers(handler); + } else { if (handler instanceof ChannelInboundHandler) { handler = new WrapperInboundHandler((ChannelInboundHandler) handler); } else { @@ -144,9 +146,8 @@ public abstract class BasePipelineFactory extends ChannelInitializer { AlertEventHandler.class, IgnitionEventHandler.class, MaintenanceEventHandler.class, - DriverEventHandler.class); - - pipeline.addLast(new MainEventHandler()); + DriverEventHandler.class, + MainEventHandler.class); } } diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index a40756796..505e7926f 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -15,6 +15,8 @@ */ package org.traccar; +import com.google.inject.Inject; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import io.netty.handler.codec.http.HttpRequestDecoder; @@ -25,6 +27,7 @@ import org.traccar.config.Keys; import org.traccar.database.CommandsManager; import org.traccar.database.ConnectionManager; import org.traccar.database.IdentityManager; +import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; import org.traccar.model.Command; @@ -53,11 +56,22 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final StatisticsManager statisticsManager; private final Protocol protocol; + private MediaManager mediaManager; + public BaseProtocolDecoder(Protocol protocol) { this.protocol = protocol; statisticsManager = Main.getInjector() != null ? Main.getInjector().getInstance(StatisticsManager.class) : null; } + @Inject + public void setMediaManager(MediaManager mediaManager) { + this.mediaManager = mediaManager; + } + + public String writeMediaFile(String uniqueId, ByteBuf buf, String extension) { + return mediaManager.writeFile(uniqueId, buf, extension); + } + public String getProtocolName() { return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; } diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index ee14f8a1a..237a34624 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -37,7 +37,6 @@ import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; import org.traccar.database.MailManager; import org.traccar.database.MaintenancesManager; -import org.traccar.database.MediaManager; import org.traccar.database.NotificationManager; import org.traccar.database.OrderManager; import org.traccar.database.PermissionsManager; @@ -114,12 +113,6 @@ public final class Context { return mailManager; } - private static MediaManager mediaManager; - - public static MediaManager getMediaManager() { - return mediaManager; - } - private static UsersManager usersManager; public static UsersManager getUsersManager() { @@ -313,8 +306,6 @@ public final class Context { mailManager = new MailManager(); - mediaManager = new MediaManager(config.getString(Keys.MEDIA_PATH)); - if (dataManager != null) { usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); @@ -390,13 +381,12 @@ public final class Context { velocityEngine.init(velocityProperties); } - public static void init(IdentityManager testIdentityManager, MediaManager testMediaManager) { + public static void init(IdentityManager testIdentityManager) { config = new Config(); objectMapper = new ObjectMapper(); objectMapper.registerModule(new JSR353Module()); client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); identityManager = testIdentityManager; - mediaManager = testMediaManager; } public static BaseObjectManager getManager(Class clazz) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index f1f2527bc..91706222a 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -30,6 +30,7 @@ import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import javax.inject.Inject; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -42,6 +43,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Set connectionlessProtocols = new HashSet<>(); private final Set logAttributes = new LinkedHashSet<>(); + @Inject public MainEventHandler() { String connectionlessProtocolList = Context.getConfig().getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java index 9322dd80a..4df848042 100644 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ b/src/main/java/org/traccar/database/GroupsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 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,7 +19,6 @@ package org.traccar.database; import java.util.HashSet; import java.util.Set; -import org.traccar.Context; import org.traccar.model.Group; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/database/MediaManager.java b/src/main/java/org/traccar/database/MediaManager.java index edade5766..5f3fdcdf7 100644 --- a/src/main/java/org/traccar/database/MediaManager.java +++ b/src/main/java/org/traccar/database/MediaManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 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. @@ -18,7 +18,10 @@ package org.traccar.database; import io.netty.buffer.ByteBuf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import javax.inject.Inject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -34,10 +37,11 @@ public class MediaManager { private static final Logger LOGGER = LoggerFactory.getLogger(MediaManager.class); - private String path; + private final String path; - public MediaManager(String path) { - this.path = path; + @Inject + public MediaManager(Config config) { + this.path = config.getString(Keys.MEDIA_PATH); } private File createFile(String uniqueId, String name) throws IOException { diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 186b81470..247a1b696 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -626,7 +626,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date(time * 1000)); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(String.valueOf(id), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(String.valueOf(id), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index c64b8171f..3c15d41eb 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -98,7 +97,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); } finally { photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 5f9326a61..53f35c3cd 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -381,7 +380,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; return position; diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index f29fb9850..eb553c5a9 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -329,7 +329,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index d74f19179..d5aa45b9c 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -361,7 +360,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); } finally { photoPackets = 0; photo.release(); diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 89931f614..832645374 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1028,8 +1028,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { sendPhotoRequest(channel, pictureId); } else { Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); - position.set( - Position.KEY_IMAGE, Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(pictureId).release(); } @@ -1265,8 +1264,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date(timestamp)); Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); - position.set(Position.KEY_IMAGE, - Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(mediaId).release(); } } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index d38e5d1c3..a25cab06f 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -472,7 +472,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); ByteBuf photo = photos.remove(imageIndex); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); } finally { photo.release(); } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 013e297c0..6fed56fb6 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -589,7 +589,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index ff92b51f1..5e24cacdc 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -182,7 +182,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 5a0383358..7abb52bd0 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -298,7 +297,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; return position; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index f83a49941..61a61b900 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -148,7 +148,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); photos.remove(photoId); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); } finally { photo.release(); } diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 420866578..3967fb804 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -313,7 +312,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int timeIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); buf.readerIndex(timeIndex + 12 + 2); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(id, buf, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(id, buf, "jpg")); return position; @@ -339,7 +338,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, audio, "amr")); + position.set(Position.KEY_AUDIO, writeMediaFile(id, audio, "amr")); audio.release(); audio = null; return position; @@ -356,7 +355,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, buf, "amr")); + position.set(Position.KEY_AUDIO, writeMediaFile(id, buf, "amr")); return position; diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 0b2c616ce..1dddbb03b 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,34 +1,9 @@ package org.traccar; -import io.netty.buffer.ByteBuf; -import org.traccar.database.MediaManager; - -import java.util.HashMap; -import java.util.Map; - public class BaseTest { - public static class MockMediaManager extends MediaManager { - Map files = new HashMap<>(); - - MockMediaManager() { - super(""); - } - - @Override - public String writeFile(String uniqueId, ByteBuf buf, String extension) { - String fileName = uniqueId + "/mock." + extension; - files.put(fileName, buf); - return fileName; - } - - public ByteBuf readFile(String fileName) { - return files.get(fileName); - } - } - static { - Context.init(new TestIdentityManager(), new MockMediaManager()); + Context.init(new TestIdentityManager()); } } diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index ef6c33da9..50baaa81a 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -1,12 +1,11 @@ package org.traccar.protocol; -import io.netty.buffer.ByteBuf; import org.junit.Test; -import org.traccar.Context; import org.traccar.ProtocolTest; +import org.traccar.database.MediaManager; import org.traccar.model.Position; -import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; public class WatchProtocolDecoderTest extends ProtocolTest { @@ -148,14 +147,15 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = new WatchProtocolDecoder(null); - verifyNull(decoder.decode(null, null, buffer("[CS*1234567890*0004*TK,1]"))); + var mediaManager = mock(MediaManager.class); + when(mediaManager.writeFile(any(), any(), any())).thenReturn("mock.amr"); + decoder.setMediaManager(mediaManager); - ByteBuf data = binary("7d5b5d2c2aff"); + verifyAttribute(decoder, concatenateBuffers( + buffer("[CS*1234567890*000e*TK,#!AMR"), binary("7d5b5d2c2aff"), buffer("]")), + Position.KEY_AUDIO, "mock.amr"); - Object decodedObject = decoder.decode(null, null, concatenateBuffers(buffer("[CS*1234567890*000e*TK,#!AMR"), data.resetReaderIndex(), buffer("]"))); - assertEquals("1234567890/mock.amr", ((Position) decodedObject).getAttributes().get("audio")); - - verifyFrame(concatenateBuffers(buffer("#!AMR"), data.resetReaderIndex()), ((MockMediaManager) Context.getMediaManager()).readFile("1234567890/mock.amr")); + verify(mediaManager).writeFile(any(), any(), any()); } -- 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 'src/main/java/org') 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 014cf82a9e63a36e944e293932f9edf27e452919 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 14:04:24 -0700 Subject: No context dependency for decoder --- src/main/java/org/traccar/BaseProtocolDecoder.java | 42 ++++++++++++++++++---- src/main/java/org/traccar/Main.java | 2 +- src/main/java/org/traccar/model/BaseModel.java | 6 ++-- src/main/java/org/traccar/model/CellTower.java | 14 ++++---- .../traccar/protocol/AplicomProtocolDecoder.java | 3 +- .../traccar/protocol/AtrackProtocolDecoder.java | 16 +++++---- .../traccar/protocol/Avl301ProtocolDecoder.java | 2 +- .../traccar/protocol/CastelProtocolDecoder.java | 4 +-- .../org/traccar/protocol/EsealProtocolDecoder.java | 9 +++-- .../org/traccar/protocol/GenxProtocolDecoder.java | 7 ++-- .../traccar/protocol/Gl200TextProtocolDecoder.java | 11 +++--- .../traccar/protocol/GlobalSatProtocolDecoder.java | 8 +++-- .../traccar/protocol/Gps103ProtocolDecoder.java | 3 +- .../org/traccar/protocol/H02ProtocolDecoder.java | 6 ++-- .../traccar/protocol/HuabaoProtocolDecoder.java | 3 +- .../org/traccar/protocol/Jt600ProtocolDecoder.java | 7 ++-- .../java/org/traccar/protocol/OrbcommProtocol.java | 3 +- .../traccar/protocol/OrbcommProtocolPoller.java | 12 +++---- .../traccar/protocol/SkypatrolProtocolDecoder.java | 9 +++-- .../traccar/protocol/StarLinkProtocolDecoder.java | 9 +++-- .../traccar/protocol/TechTltProtocolDecoder.java | 2 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 11 ++++-- .../traccar/protocol/ThinkRaceProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 9 +++-- .../org/traccar/protocol/TotemProtocolDecoder.java | 6 ++-- .../org/traccar/protocol/TzoneProtocolDecoder.java | 5 ++- .../org/traccar/protocol/XirgoProtocolDecoder.java | 7 ++-- .../traccar/protocol/Xt2400ProtocolDecoder.java | 6 ++-- src/test/java/org/traccar/BaseTest.java | 30 ++++++++++++++++ .../org/traccar/protocol/AdmFrameDecoderTest.java | 2 +- .../traccar/protocol/AdmProtocolDecoderTest.java | 2 +- .../traccar/protocol/AisProtocolDecoderTest.java | 2 +- .../protocol/AlematicsProtocolDecoderTest.java | 2 +- .../protocol/AnytrekProtocolDecoderTest.java | 2 +- .../traccar/protocol/ApelProtocolDecoderTest.java | 2 +- .../traccar/protocol/AplicomFrameDecoderTest.java | 2 +- .../protocol/AplicomProtocolDecoderTest.java | 2 +- .../protocol/AppelloProtocolDecoderTest.java | 2 +- .../protocol/AquilaProtocolDecoderTest.java | 2 +- .../protocol/Ardi01ProtocolDecoderTest.java | 2 +- .../protocol/ArknavProtocolDecoderTest.java | 2 +- .../protocol/ArknavX8ProtocolDecoderTest.java | 2 +- .../protocol/ArmoliProtocolDecoderTest.java | 2 +- .../protocol/ArnaviBinaryProtocolDecoderTest.java | 8 ++--- .../traccar/protocol/ArnaviFrameDecoderTest.java | 2 +- .../protocol/ArnaviTextProtocolDecoderTest.java | 2 +- .../traccar/protocol/AstraProtocolDecoderTest.java | 2 +- .../traccar/protocol/At2000FrameDecoderTest.java | 2 +- .../traccar/protocol/AtrackFrameDecoderTest.java | 2 +- .../protocol/AtrackProtocolDecoderTest.java | 4 +-- .../traccar/protocol/AuroProtocolDecoderTest.java | 2 +- .../protocol/AustinNbProtocolDecoderTest.java | 2 +- .../protocol/AutoFonProtocolDecoderTest.java | 2 +- .../protocol/AutoGradeProtocolDecoderTest.java | 2 +- .../protocol/AutoTrackProtocolDecoderTest.java | 2 +- .../traccar/protocol/AvemaProtocolDecoderTest.java | 2 +- .../protocol/Avl301ProtocolDecoderTest.java | 2 +- .../traccar/protocol/B2316ProtocolDecoderTest.java | 2 +- .../traccar/protocol/BceProtocolDecoderTest.java | 2 +- .../protocol/BlackKiteProtocolDecoderTest.java | 2 +- .../traccar/protocol/BlueProtocolDecoderTest.java | 2 +- .../traccar/protocol/BoxProtocolDecoderTest.java | 2 +- .../protocol/C2stekProtocolDecoderTest.java | 2 +- .../protocol/CalAmpProtocolDecoderTest.java | 2 +- .../protocol/CarTrackProtocolDecoderTest.java | 2 +- .../protocol/CarscopProtocolDecoderTest.java | 2 +- .../protocol/CastelProtocolDecoderTest.java | 2 +- .../protocol/CautelaProtocolDecoderTest.java | 2 +- .../protocol/CellocatorFrameDecoderTest.java | 2 +- .../protocol/CellocatorProtocolDecoderTest.java | 2 +- .../protocol/CguardProtocolDecoderTest.java | 2 +- .../protocol/CityeasyProtocolDecoderTest.java | 2 +- .../protocol/ContinentalProtocolDecoderTest.java | 2 +- .../protocol/CradlepointProtocolDecoderTest.java | 2 +- .../traccar/protocol/DingtekFrameDecoderTest.java | 2 +- .../protocol/DingtekProtocolDecoderTest.java | 2 +- .../traccar/protocol/DishaProtocolDecoderTest.java | 2 +- .../protocol/DmtHttpProtocolDecoderTest.java | 2 +- .../traccar/protocol/DmtProtocolDecoderTest.java | 2 +- .../protocol/DolphinProtocolDecoderTest.java | 2 +- .../traccar/protocol/Dsf22FrameDecoderTest.java | 2 +- .../traccar/protocol/Dsf22ProtocolDecoderTest.java | 2 +- .../traccar/protocol/DualcamFrameDecoderTest.java | 2 +- .../protocol/DualcamProtocolDecoderTest.java | 2 +- .../traccar/protocol/DwayProtocolDecoderTest.java | 2 +- .../protocol/EasyTrackProtocolDecoderTest.java | 2 +- .../protocol/EelinkProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/EgtsFrameDecoderTest.java | 2 +- .../traccar/protocol/EgtsProtocolDecoderTest.java | 4 +-- .../protocol/EnforaProtocolDecoderTest.java | 2 +- .../traccar/protocol/EnnfuProtocolDecoderTest.java | 2 +- .../protocol/EnvotechProtocolDecoderTest.java | 2 +- .../traccar/protocol/EsealProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/EskyFrameDecoderTest.java | 2 +- .../traccar/protocol/EskyProtocolDecoderTest.java | 2 +- .../protocol/ExtremTracProtocolDecoderTest.java | 2 +- .../protocol/FifotrackFrameDecoderTest.java | 2 +- .../protocol/FifotrackProtocolDecoderTest.java | 2 +- .../protocol/FlespiProtocolDecoderTest.java | 2 +- .../protocol/FlexApiProtocolDecoderTest.java | 2 +- .../protocol/FlexCommProtocolDecoderTest.java | 2 +- .../FlexibleReportProtocolDecoderTest.java | 2 +- .../protocol/FlextrackProtocolDecoderTest.java | 2 +- .../traccar/protocol/FoxProtocolDecoderTest.java | 2 +- .../protocol/FreedomProtocolDecoderTest.java | 2 +- .../protocol/FreematicsProtocolDecoderTest.java | 2 +- .../protocol/FutureWayFrameDecoderTest.java | 2 +- .../protocol/FutureWayProtocolDecoderTest.java | 2 +- .../traccar/protocol/GalileoFrameDecoderTest.java | 2 +- .../protocol/GalileoProtocolDecoderTest.java | 2 +- .../traccar/protocol/GatorProtocolDecoderTest.java | 2 +- .../traccar/protocol/GenxProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gl100ProtocolDecoderTest.java | 2 +- .../protocol/Gl200BinaryProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gl200FrameDecoderTest.java | 2 +- .../protocol/Gl200TextProtocolDecoderTest.java | 2 +- .../protocol/GlobalSatProtocolDecoderTest.java | 2 +- .../protocol/GlobalstarProtocolDecoderTest.java | 2 +- .../traccar/protocol/GnxProtocolDecoderTest.java | 2 +- .../protocol/GoSafeProtocolDecoderTest.java | 2 +- .../traccar/protocol/GotopProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gps056FrameDecoderTest.java | 2 +- .../protocol/Gps056ProtocolDecoderTest.java | 2 +- .../protocol/Gps103ProtocolDecoderTest.java | 2 +- .../protocol/GpsGateProtocolDecoderTest.java | 2 +- .../protocol/GpsMarkerProtocolDecoderTest.java | 2 +- .../protocol/GpsmtaProtocolDecoderTest.java | 2 +- .../traccar/protocol/GranitFrameDecoderTest.java | 2 +- .../protocol/GranitProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gs100ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gt02ProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/Gt06FrameDecoderTest.java | 2 +- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gt30ProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/H02FrameDecoderTest.java | 6 ++-- .../traccar/protocol/H02ProtocolDecoderTest.java | 4 +-- .../protocol/HaicomProtocolDecoderTest.java | 2 +- .../protocol/HomtecsProtocolDecoderTest.java | 2 +- .../traccar/protocol/HoopoProtocolDecoderTest.java | 2 +- .../traccar/protocol/HuaShengFrameDecoderTest.java | 2 +- .../protocol/HuaShengProtocolDecoderTest.java | 2 +- .../traccar/protocol/HuabaoFrameDecoderTest.java | 2 +- .../protocol/HuabaoProtocolDecoderTest.java | 2 +- .../protocol/HunterProProtocolDecoderTest.java | 2 +- .../traccar/protocol/IdplProtocolDecoderTest.java | 2 +- .../protocol/IntellitracProtocolDecoderTest.java | 2 +- .../traccar/protocol/IotmProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/ItsFrameDecoderTest.java | 2 +- .../traccar/protocol/ItsProtocolDecoderTest.java | 2 +- .../protocol/Ivt401ProtocolDecoderTest.java | 2 +- .../traccar/protocol/JidoProtocolDecoderTest.java | 2 +- .../protocol/JpKorjarProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/JsonFrameDecoderTest.java | 2 +- .../traccar/protocol/Jt600FrameDecoderTest.java | 2 +- .../traccar/protocol/Jt600ProtocolDecoderTest.java | 2 +- .../traccar/protocol/KenjiProtocolDecoderTest.java | 2 +- .../traccar/protocol/KhdProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/L100FrameDecoderTest.java | 2 +- .../traccar/protocol/L100ProtocolDecoderTest.java | 2 +- .../traccar/protocol/LacakProtocolDecoderTest.java | 2 +- .../protocol/LaipacProtocolDecoderTest.java | 2 +- .../protocol/LeafSpyProtocolDecoderTest.java | 2 +- .../traccar/protocol/M2cProtocolDecoderTest.java | 2 +- .../traccar/protocol/M2mProtocolDecoderTest.java | 2 +- .../protocol/MaestroProtocolDecoderTest.java | 2 +- .../protocol/ManPowerProtocolDecoderTest.java | 2 +- .../protocol/Mavlink2ProtocolDecoderTest.java | 2 +- .../traccar/protocol/MegastekFrameDecoderTest.java | 2 +- .../protocol/MegastekProtocolDecoderTest.java | 2 +- .../traccar/protocol/MeiligaoFrameDecoderTest.java | 2 +- .../protocol/MeiligaoProtocolDecoderTest.java | 2 +- .../traccar/protocol/MeitrackFrameDecoderTest.java | 2 +- .../protocol/MeitrackProtocolDecoderTest.java | 2 +- .../protocol/MictrackProtocolDecoderTest.java | 4 +-- .../protocol/MilesmateProtocolDecoderTest.java | 2 +- .../protocol/MiniFinderProtocolDecoderTest.java | 2 +- .../protocol/Minifinder2ProtocolDecoderTest.java | 2 +- .../protocol/MobilogixProtocolDecoderTest.java | 2 +- .../protocol/MoovboxProtocolDecoderTest.java | 2 +- .../traccar/protocol/MotorProtocolDecoderTest.java | 2 +- .../traccar/protocol/MtxProtocolDecoderTest.java | 2 +- .../traccar/protocol/MxtProtocolDecoderTest.java | 2 +- .../protocol/NavigilProtocolDecoderTest.java | 2 +- .../traccar/protocol/NavisProtocolDecoderTest.java | 6 ++-- .../traccar/protocol/NavisetFrameDecoderTest.java | 2 +- .../protocol/NavisetProtocolDecoderTest.java | 2 +- .../protocol/NavtelecomFrameDecoderTest.java | 4 +-- .../protocol/NavtelecomProtocolDecoderTest.java | 2 +- .../traccar/protocol/NeosProtocolDecoderTest.java | 2 +- .../traccar/protocol/NetProtocolDecoderTest.java | 2 +- .../traccar/protocol/NiotProtocolDecoderTest.java | 2 +- .../traccar/protocol/NoranProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/NvsFrameDecoderTest.java | 2 +- .../traccar/protocol/NvsProtocolDecoderTest.java | 2 +- .../protocol/NyitechProtocolDecoderTest.java | 2 +- .../protocol/ObdDongleProtocolDecoderTest.java | 2 +- .../traccar/protocol/OigoProtocolDecoderTest.java | 2 +- .../traccar/protocol/OkoProtocolDecoderTest.java | 2 +- .../traccar/protocol/OmnicommFrameDecoderTest.java | 2 +- .../protocol/OmnicommProtocolDecoderTest.java | 2 +- .../protocol/OpenGtsProtocolDecoderTest.java | 2 +- .../protocol/OrbcommProtocolDecoderTest.java | 2 +- .../traccar/protocol/OrionProtocolDecoderTest.java | 2 +- .../protocol/OsmAndProtocolDecoderTest.java | 2 +- .../protocol/OutsafeProtocolDecoderTest.java | 2 +- .../protocol/OwnTracksProtocolDecoderTest.java | 2 +- .../protocol/PacificTrackProtocolDecoderTest.java | 2 +- .../protocol/PathAwayProtocolDecoderTest.java | 2 +- .../protocol/PiligrimProtocolDecoderTest.java | 2 +- .../protocol/PluginProtocolDecoderTest.java | 2 +- .../traccar/protocol/PolteProtocolDecoderTest.java | 2 +- .../protocol/PortmanProtocolDecoderTest.java | 2 +- .../protocol/PretraceProtocolDecoderTest.java | 2 +- .../protocol/PricolProtocolDecoderTest.java | 2 +- .../protocol/ProgressProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/PstFrameDecoderTest.java | 2 +- .../traccar/protocol/PstProtocolDecoderTest.java | 2 +- .../traccar/protocol/Pt215ProtocolDecoderTest.java | 2 +- .../protocol/Pt3000ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Pt502FrameDecoderTest.java | 2 +- .../traccar/protocol/Pt502ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Pt60ProtocolDecoderTest.java | 2 +- .../traccar/protocol/R12wProtocolDecoderTest.java | 2 +- .../protocol/RaceDynamicsProtocolDecoderTest.java | 2 +- .../traccar/protocol/RadarProtocolDecoderTest.java | 2 +- .../protocol/RaveonProtocolDecoderTest.java | 2 +- .../protocol/RecodaProtocolDecoderTest.java | 2 +- .../protocol/RetranslatorProtocolDecoderTest.java | 2 +- .../traccar/protocol/RitiProtocolDecoderTest.java | 2 +- .../protocol/RoboTrackFrameDecoderTest.java | 2 +- .../protocol/RoboTrackProtocolDecoderTest.java | 2 +- .../traccar/protocol/RstProtocolDecoderTest.java | 2 +- .../protocol/RuptelaProtocolDecoderTest.java | 2 +- .../traccar/protocol/S168ProtocolDecoderTest.java | 2 +- .../traccar/protocol/SabertekFrameDecoderTest.java | 2 +- .../protocol/SabertekProtocolDecoderTest.java | 2 +- .../traccar/protocol/SanavProtocolDecoderTest.java | 2 +- .../traccar/protocol/SanulProtocolDecoderTest.java | 2 +- .../protocol/SatsolProtocolDecoderTest.java | 2 +- .../protocol/SigfoxProtocolDecoderTest.java | 2 +- .../traccar/protocol/SiwiProtocolDecoderTest.java | 2 +- .../protocol/SkypatrolProtocolDecoderTest.java | 2 +- .../protocol/SmartSoleProtocolDecoderTest.java | 2 +- .../protocol/SmokeyProtocolDecoderTest.java | 2 +- .../protocol/SolarPoweredProtocolDecoderTest.java | 2 +- .../traccar/protocol/SpotProtocolDecoderTest.java | 2 +- .../protocol/StarLinkProtocolDecoderTest.java | 2 +- .../protocol/StarcomProtocolDecoderTest.java | 2 +- .../protocol/StartekProtocolDecoderTest.java | 2 +- .../traccar/protocol/StbProtocolDecoderTest.java | 2 +- .../protocol/Stl060ProtocolDecoderTest.java | 2 +- .../traccar/protocol/SuntechFrameDecoderTest.java | 2 +- .../protocol/SuntechProtocolDecoderTest.java | 12 +++---- .../protocol/SupermateProtocolDecoderTest.java | 2 +- .../traccar/protocol/SviasProtocolDecoderTest.java | 2 +- .../protocol/SwiftechProtocolDecoderTest.java | 2 +- .../traccar/protocol/T55ProtocolDecoderTest.java | 4 +-- .../org/traccar/protocol/T57FrameDecoderTest.java | 2 +- .../traccar/protocol/T57ProtocolDecoderTest.java | 2 +- .../traccar/protocol/T800xProtocolDecoderTest.java | 2 +- .../traccar/protocol/TaipProtocolDecoderTest.java | 2 +- .../protocol/TechTltProtocolDecoderTest.java | 2 +- .../protocol/TechtoCruzFrameDecoderTest.java | 2 +- .../protocol/TechtoCruzProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/TekFrameDecoderTest.java | 2 +- .../traccar/protocol/TekProtocolDecoderTest.java | 2 +- .../protocol/TelemaxProtocolDecoderTest.java | 2 +- .../traccar/protocol/TelicFrameDecoderTest.java | 2 +- .../traccar/protocol/TelicProtocolDecoderTest.java | 2 +- .../protocol/TeltonikaFrameDecoderTest.java | 2 +- .../protocol/TeltonikaProtocolDecoderTest.java | 6 ++-- .../protocol/TeraTrackProtocolDecoderTest.java | 2 +- .../protocol/ThinkPowerProtocolDecoderTest.java | 2 +- .../protocol/ThinkRaceProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tk102ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tk103FrameDecoderTest.java | 2 +- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tlt2hProtocolDecoderTest.java | 2 +- .../traccar/protocol/TlvProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/TmgFrameDecoderTest.java | 2 +- .../traccar/protocol/TmgProtocolDecoderTest.java | 2 +- .../protocol/TopflytechProtocolDecoderTest.java | 2 +- .../traccar/protocol/TopinProtocolDecoderTest.java | 2 +- .../traccar/protocol/TotemFrameDecoderTest.java | 2 +- .../traccar/protocol/TotemProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tr20ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tr900ProtocolDecoderTest.java | 2 +- .../protocol/TrackboxProtocolDecoderTest.java | 2 +- .../protocol/TrakMateProtocolDecoderTest.java | 2 +- .../traccar/protocol/TramigoFrameDecoderTest.java | 2 +- .../protocol/TramigoProtocolDecoderTest.java | 2 +- .../traccar/protocol/TrvProtocolDecoderTest.java | 2 +- .../protocol/Tt8850ProtocolDecoderTest.java | 2 +- .../traccar/protocol/TytanProtocolDecoderTest.java | 2 +- .../traccar/protocol/TzoneProtocolDecoderTest.java | 2 +- .../traccar/protocol/UlbotechFrameDecoderTest.java | 2 +- .../protocol/UlbotechProtocolDecoderTest.java | 2 +- .../traccar/protocol/UproProtocolDecoderTest.java | 2 +- .../traccar/protocol/UuxProtocolDecoderTest.java | 2 +- .../traccar/protocol/V680ProtocolDecoderTest.java | 2 +- .../protocol/VisiontekProtocolDecoderTest.java | 2 +- .../traccar/protocol/VnetProtocolDecoderTest.java | 2 +- .../traccar/protocol/Vt200FrameDecoderTest.java | 2 +- .../traccar/protocol/Vt200ProtocolDecoderTest.java | 2 +- .../traccar/protocol/VtfmsFrameDecoderTest.java | 2 +- .../traccar/protocol/VtfmsProtocolDecoderTest.java | 2 +- .../traccar/protocol/WatchFrameDecoderTest.java | 2 +- .../traccar/protocol/WatchProtocolDecoderTest.java | 4 +-- .../protocol/WialonProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/WliFrameDecoderTest.java | 2 +- .../traccar/protocol/WliProtocolDecoderTest.java | 2 +- .../traccar/protocol/WondexFrameDecoderTest.java | 2 +- .../protocol/WondexProtocolDecoderTest.java | 2 +- .../protocol/WristbandProtocolDecoderTest.java | 2 +- .../traccar/protocol/Xexun2FrameDecoderTest.java | 2 +- .../protocol/Xexun2ProtocolDecoderTest.java | 2 +- .../traccar/protocol/XexunFrameDecoderTest.java | 2 +- .../traccar/protocol/XexunProtocolDecoderTest.java | 11 ++++-- .../traccar/protocol/XirgoProtocolDecoderTest.java | 6 ++-- .../traccar/protocol/Xrb28ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Xt013ProtocolDecoderTest.java | 2 +- .../protocol/Xt2400ProtocolDecoderTest.java | 2 +- .../traccar/protocol/YwtProtocolDecoderTest.java | 2 +- 323 files changed, 495 insertions(+), 402 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 505e7926f..0f62c87df 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -50,17 +50,47 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private static final String PROTOCOL_UNKNOWN = "unknown"; - private final Config config = Context.getConfig(); - private final IdentityManager identityManager = Context.getIdentityManager(); - private final ConnectionManager connectionManager = Context.getConnectionManager(); - private final StatisticsManager statisticsManager; private final Protocol protocol; + private Config config; + private IdentityManager identityManager; + private ConnectionManager connectionManager; + private StatisticsManager statisticsManager; private MediaManager mediaManager; public BaseProtocolDecoder(Protocol protocol) { this.protocol = protocol; - statisticsManager = Main.getInjector() != null ? Main.getInjector().getInstance(StatisticsManager.class) : null; + } + + /** + * Method called when config is initialized. + */ + protected void init() { + } + + public Config getConfig() { + return config; + } + + @Inject + public void setConfig(Config config) { + this.config = config; + init(); + } + + @Inject + public void setIdentityManager(IdentityManager identityManager) { + this.identityManager = identityManager; + } + + @Inject + public void setConnectionManager(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; + } + + @Inject + public void setStatisticsManager(StatisticsManager statisticsManager) { + this.statisticsManager = statisticsManager; } @Inject diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 2eaf394af..016365837 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -110,8 +110,8 @@ public final class Main { public static void run(String configFile) { try { - Context.init(configFile); injector = Guice.createInjector(new MainModule()); + Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); diff --git a/src/main/java/org/traccar/model/BaseModel.java b/src/main/java/org/traccar/model/BaseModel.java index 8bdb916e8..acde0f83d 100644 --- a/src/main/java/org/traccar/model/BaseModel.java +++ b/src/main/java/org/traccar/model/BaseModel.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"); @@ -20,11 +20,11 @@ public class BaseModel { private long id; - public final long getId() { + public long getId() { return id; } - public final void setId(long id) { + public void setId(long id) { this.id = id; } diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index 254487471..af33b1f5c 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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. @@ -16,7 +16,7 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonInclude; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; @JsonInclude(JsonInclude.Include.NON_NULL) @@ -37,14 +37,12 @@ public class CellTower { return cellTower; } - public static CellTower fromLacCid(int lac, long cid) { - return from( - Context.getConfig().getInteger(Keys.GEOLOCATION_MCC), - Context.getConfig().getInteger(Keys.GEOLOCATION_MCC), lac, cid); + public static CellTower fromLacCid(Config config, int lac, long cid) { + return from(config.getInteger(Keys.GEOLOCATION_MCC), config.getInteger(Keys.GEOLOCATION_MCC), lac, cid); } - public static CellTower fromCidLac(long cid, int lac) { - return fromLacCid(lac, cid); + public static CellTower fromCidLac(Config config, long cid, int lac) { + return fromLacCid(config, lac, cid); } private String radioType; diff --git a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java index f11312428..692a2058a 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java @@ -21,7 +21,6 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -303,7 +302,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { decodeEventData(position, buf, event); } - if (Context.getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getProtocolName())) + if (getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getProtocolName())) && buf.isReadable() && (selector & 0x1000) != 0 && event == EVENT_DATA) { decodeCanData(buf, position); } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 247a1b696..9a5d537ef 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -54,7 +53,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private static final int MIN_DATA_LENGTH = 40; private boolean longDate; - private final boolean decimalFuel; + private boolean decimalFuel; private boolean custom; private String form; @@ -64,17 +63,20 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { public AtrackProtocolDecoder(Protocol protocol) { super(protocol); + } - longDate = Context.getConfig().getBoolean(Keys.PROTOCOL_LONG_DATE.withPrefix(getProtocolName())); - decimalFuel = Context.getConfig().getBoolean(Keys.PROTOCOL_DECIMAL_FUEL.withPrefix(getProtocolName())); + @Override + protected void init() { + longDate = getConfig().getBoolean(Keys.PROTOCOL_LONG_DATE.withPrefix(getProtocolName())); + decimalFuel = getConfig().getBoolean(Keys.PROTOCOL_DECIMAL_FUEL.withPrefix(getProtocolName())); - custom = Context.getConfig().getBoolean(Keys.PROTOCOL_CUSTOM.withPrefix(getProtocolName())); - form = Context.getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); + custom = getConfig().getBoolean(Keys.PROTOCOL_CUSTOM.withPrefix(getProtocolName())); + form = getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); if (form != null) { custom = true; } - String alarmMapString = Context.getConfig().getString(Keys.PROTOCOL_ALARM_MAP.withPrefix(getProtocolName())); + String alarmMapString = getConfig().getString(Keys.PROTOCOL_ALARM_MAP.withPrefix(getProtocolName())); if (alarmMapString != null) { for (String pair : alarmMapString.split(",")) { if (!pair.isEmpty()) { diff --git a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java index f6b7db2d6..9f6ded26a 100644 --- a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java @@ -125,7 +125,7 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder { } position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedMedium()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedMedium()))); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); int flags = buf.readUnsignedByte(); diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 23401b5ee..85ac29336 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -443,7 +443,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { decodeStat(position, buf); position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); return position; @@ -499,7 +499,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // additional flags position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); positions.add(position); } diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index 0a12f781d..27fcf1394 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -32,11 +31,15 @@ import java.util.regex.Pattern; public class EsealProtocolDecoder extends BaseProtocolDecoder { - private final String config; + private String config; public EsealProtocolDecoder(Protocol protocol) { super(protocol); - config = Context.getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + config = getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); } private static final Pattern PATTERN = new PatternBuilder() diff --git a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java index 2ae9de7a0..b787b7467 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; @@ -32,7 +31,11 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { public GenxProtocolDecoder(Protocol protocol) { super(protocol); - setReportColumns(Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); + } + + @Override + protected void init() { + setReportColumns(getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); } public void setReportColumns(String format) { diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 280986165..72d3ef592 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -16,7 +16,6 @@ package org.traccar.protocol; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -46,11 +45,15 @@ import java.util.regex.Pattern; public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { - private final boolean ignoreFixTime; + private boolean ignoreFixTime; public Gl200TextProtocolDecoder(Protocol protocol) { super(protocol); - ignoreFixTime = Context.getConfig().getBoolean(Keys.PROTOCOL_IGNORE_FIX_TIME.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + ignoreFixTime = getConfig().getBoolean(Keys.PROTOCOL_IGNORE_FIX_TIME.withPrefix(getProtocolName())); } private static final Pattern PATTERN_ACK = new PatternBuilder() @@ -1333,7 +1336,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } } - if (channel != null && Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + if (channel != null && getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { String checksum; if (sentence.endsWith("$")) { checksum = sentence.substring(sentence.length() - 1 - 4, sentence.length() - 1); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java index b48df4047..d5c834284 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -40,9 +39,12 @@ public class GlobalSatProtocolDecoder extends BaseProtocolDecoder { public GlobalSatProtocolDecoder(Protocol protocol) { super(protocol); + } - format0 = Context.getConfig().getString(getProtocolName() + ".format0", "TSPRXAB27GHKLMnaicz*U!"); - format1 = Context.getConfig().getString(getProtocolName() + ".format1", "SARY*U!"); + @Override + protected void init() { + format0 = getConfig().getString(getProtocolName() + ".format0", "TSPRXAB27GHKLMnaicz*U!"); + format1 = getConfig().getString(getProtocolName() + ".format1", "SARY*U!"); } public void setFormat0(String format) { diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index d5aa45b9c..510f5eca2 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -221,7 +221,8 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + position.setNetwork(new Network(CellTower.fromLacCid( + getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); } else { diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index 10a272bff..dcfb36fd1 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -334,7 +333,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext() && parser.next().equals("V1")) { sendResponse(channel, remoteAddress, id, "V1"); - } else if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + } else if (getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { sendResponse(channel, remoteAddress, id, "R12"); } @@ -392,7 +391,8 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(parser.nextInt(0)); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + position.setNetwork(new Network(CellTower.fromLacCid( + getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); } if (parser.hasNext()) { diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 9f54c8486..84120028a 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -585,7 +585,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, true); } - position.setNetwork(new Network(CellTower.fromCidLac(buf.readUnsignedInt(), buf.readUnsignedShort()))); + position.setNetwork(new Network(CellTower.fromCidLac( + getConfig(), buf.readUnsignedInt(), buf.readUnsignedShort()))); int product = buf.readUnsignedByte(); int status = buf.readUnsignedShort(); diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index b4b70091b..2c1b5dcec 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -177,7 +177,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, battery); } - CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); + CellTower cellTower = CellTower.fromCidLac( + getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()); cellTower.setSignalStrength((int) buf.readUnsignedByte()); position.setNetwork(new Network(cellTower)); @@ -201,7 +202,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { int rssi = buf.readUnsignedByte(); if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromCidLac(cid, lac); + CellTower cellTower = CellTower.fromCidLac(getConfig(), cid, lac); cellTower.setSignalStrength(rssi); position.setNetwork(new Network(cellTower)); } else { @@ -356,7 +357,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); position.set(Position.KEY_STATUS, parser.nextBinInt(0)); - CellTower cellTower = CellTower.fromCidLac(parser.nextInt(0), parser.nextInt(0)); + CellTower cellTower = CellTower.fromCidLac(getConfig(), parser.nextInt(0), parser.nextInt(0)); cellTower.setSignalStrength(parser.nextInt(0)); position.setNetwork(new Network(cellTower)); diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java index bdfce3b1e..2f9f56641 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocol.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpResponseDecoder; import org.traccar.BaseProtocol; +import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerClient; @@ -32,7 +33,7 @@ public class OrbcommProtocol extends BaseProtocol { pipeline.addLast(new HttpResponseDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new OrbcommProtocolDecoder(OrbcommProtocol.this)); - pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this)); + pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this, Context.getConfig())); } }); } diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java index 6a2d7a92d..0f57bfb49 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -24,8 +24,8 @@ import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringEncoder; import org.traccar.BaseProtocolPoller; -import org.traccar.Context; import org.traccar.Protocol; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.net.SocketAddress; @@ -46,11 +46,11 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { this.startTime = startTime; } - public OrbcommProtocolPoller(Protocol protocol) { - super(Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); - accessId = Context.getConfig().getString(Keys.ORBCOMM_ACCESS_ID); - password = Context.getConfig().getString(Keys.ORBCOMM_PASSWORD); - host = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); + public OrbcommProtocolPoller(Protocol protocol, Config config) { + super(config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); + accessId = config.getString(Keys.ORBCOMM_ACCESS_ID); + password = config.getString(Keys.ORBCOMM_PASSWORD); + host = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); } @Override diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java index 8aae310bb..818acd805 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -35,11 +34,15 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder { private static final Logger LOGGER = LoggerFactory.getLogger(SkypatrolProtocolDecoder.class); - private final long defaultMask; + private long defaultMask; public SkypatrolProtocolDecoder(Protocol protocol) { super(protocol); - defaultMask = Context.getConfig().getInteger(Keys.PROTOCOL_MASK.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + defaultMask = getConfig().getInteger(Keys.PROTOCOL_MASK.withPrefix(getProtocolName())); } private static double convertCoordinate(long coordinate) { diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 7a6b6f4fe..5e631017e 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -55,12 +55,15 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { public StarLinkProtocolDecoder(Protocol protocol) { super(protocol); + } - setFormat(Context.getConfig().getString( + @Override + protected void init() { + setFormat(getConfig().getString( getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#," + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#")); - setDateFormat(Context.getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); + setDateFormat(getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); } public String[] getFormat(long deviceId) { @@ -313,7 +316,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } if (lac != null && cid != null) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), lac, cid))); } if (event == 20) { diff --git a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java index 17f5c80fa..b6091136a 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java @@ -110,7 +110,7 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextInt(), parser.nextInt()))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), parser.nextInt(), parser.nextInt()))); return position; } diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 61a61b900..407488527 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -55,7 +55,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { public TeltonikaProtocolDecoder(Protocol protocol, boolean connectionless) { super(protocol); this.connectionless = connectionless; - this.extended = Context.getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + this.extended = getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getProtocolName())); } private void parseIdentification(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { @@ -360,7 +364,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { long cid = position.getLong(Position.PREFIX_IO + 205); int lac = position.getInteger(Position.PREFIX_IO + 206); if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromLacCid(lac, cid); + CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); long operator = position.getInteger(Position.KEY_OPERATOR); if (operator >= 1000) { cellTower.setOperator(operator); @@ -422,7 +426,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(locationMask, 5)) { - CellTower cellTower = CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()); + CellTower cellTower = CellTower.fromLacCid( + getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()); if (BitUtil.check(locationMask, 6)) { cellTower.setSignalStrength((int) buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java index 0928b25e0..82033598d 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java @@ -104,7 +104,7 @@ public class ThinkRaceProtocolDecoder extends BaseProtocolDecoder { position.setCourse(buf.readUnsignedByte()); position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()))); return position; diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index ff33cb103..476d1d682 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -36,11 +35,15 @@ import java.util.regex.Pattern; public class Tk103ProtocolDecoder extends BaseProtocolDecoder { - private final boolean decodeLow; + private boolean decodeLow; public Tk103ProtocolDecoder(Protocol protocol) { super(protocol); - decodeLow = Context.getConfig().getBoolean(Keys.PROTOCOL_DECODE_LOW.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + decodeLow = getConfig().getBoolean(Keys.PROTOCOL_DECODE_LOW.withPrefix(getProtocolName())); } private static final Pattern PATTERN = new PatternBuilder() diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 58c66031e..b76d5b307 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -320,7 +320,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { int lac = parser.nextHexInt(0); int cid = parser.nextHexInt(0); if (lac != 0 && cid != 0) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), lac, cid))); } position.set(Position.PREFIX_TEMP + 1, parser.next()); @@ -346,7 +346,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 2, parser.next()); position.setNetwork(new Network( - CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + CellTower.fromLacCid(getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); position.setValid(parser.next().equals("A")); position.set(Position.KEY_SATELLITES, parser.nextInt()); @@ -403,7 +403,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { int mcc = parser.nextInt(); cellTower = CellTower.from(mcc, mnc, lac, cid); } else { - cellTower = CellTower.fromLacCid(lac, cid); + cellTower = CellTower.fromLacCid(getConfig(), lac, cid); } position.set(Position.KEY_SATELLITES, parser.nextInt()); cellTower.setSignalStrength(parser.nextInt()); diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 819c42471..b1ddc5203 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -284,7 +283,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { if (hardware == 0x10A || hardware == 0x10B || hardware == 0x406) { position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()))); } else if (hardware == 0x407) { @@ -371,7 +370,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } - if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + if (getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { sendResponse(channel, remoteAddress, buf.getUnsignedShort(buf.writerIndex() - 6)); } diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java index 630fe5aed..b53a42ac3 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java @@ -18,7 +18,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.nio.NioDatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -40,7 +39,11 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { public XirgoProtocolDecoder(Protocol protocol) { super(protocol); - form = Context.getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + form = getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); } public void setForm(String form) { diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java index 85e8e140f..b3f6493a8 100644 --- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -18,7 +18,6 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -38,8 +37,11 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { public Xt2400ProtocolDecoder(Protocol protocol) { super(protocol); + } - String config = Context.getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); + @Override + protected void init() { + String config = getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); if (config != null) { setConfig(config); } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 1dddbb03b..35374a363 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,9 +1,39 @@ package org.traccar; +import org.traccar.config.Config; +import org.traccar.database.ConnectionManager; +import org.traccar.database.IdentityManager; +import org.traccar.database.MediaManager; +import org.traccar.database.StatisticsManager; +import org.traccar.model.Device; + +import static org.mockito.Mockito.*; + public class BaseTest { static { Context.init(new TestIdentityManager()); } + protected T inject(T decoder) throws Exception { + decoder.setConfig(new Config()); + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + var identityManager = mock(IdentityManager.class); + when(identityManager.getByUniqueId(any())).thenReturn(device); + decoder.setIdentityManager(identityManager); + decoder.setConnectionManager(mock(ConnectionManager.class)); + decoder.setStatisticsManager(mock(StatisticsManager.class)); + decoder.setMediaManager(mock(MediaManager.class)); + return decoder; + } + + protected T inject(T decoder) throws Exception { + return decoder; + } + + protected T inject(T encoder) throws Exception { + return encoder; + } + } diff --git a/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java b/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java index 1682ca56d..02d42447e 100644 --- a/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java @@ -8,7 +8,7 @@ public class AdmFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AdmFrameDecoder(); + var decoder = inject(new AdmFrameDecoder()); verifyFrame( binary("38363931353330343235323337383400003728e000001402441d5f42c3711642930d000000c7000a461954f25fd82ed508000000000000000044000000010000000000140000"), diff --git a/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java index 7c8769925..810d53bf7 100644 --- a/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AdmProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AdmProtocolDecoder(null); + var decoder = inject(new AdmProtocolDecoder(null)); verifyPosition(decoder, binary( "38363931353330343235323337383400003728e000001402441d5f42c3711642930d000000c7000a461954f25fd82ed508000000000000000044000000010000000000140000")); diff --git a/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java index f869ab8f3..36ea3d361 100644 --- a/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AisProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AisProtocolDecoder(null); + var decoder = inject(new AisProtocolDecoder(null)); verifyPositions(decoder, text( "!AIVDM,2,1,8,A,53UlSb01l>Ei=H4KF218PTpv222222222222221?8h=766gB004410C2482>03410F56>03412F19>0441210000>034130FF>0441313A7>03410D30>04411F01B6>0341048C>04410C1C98];"), diff --git a/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java index f2940de59..f96da5203 100644 --- a/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java @@ -8,9 +8,7 @@ public class ArnaviBinaryProtocolDecoderTest extends ProtocolTest { @Test public void testHeader1Decode() throws Exception { - ArnaviBinaryProtocolDecoder decoder; - - decoder = new ArnaviBinaryProtocolDecoder(null); + var decoder = inject(new ArnaviBinaryProtocolDecoder(null)); verifyNull(decoder, binary( "ff22f30c45f5c90f0300")); @@ -23,9 +21,7 @@ public class ArnaviBinaryProtocolDecoderTest extends ProtocolTest { @Test public void testHeader2Decode() throws Exception { - ArnaviBinaryProtocolDecoder decoder; - - decoder = new ArnaviBinaryProtocolDecoder(null); + var decoder = inject(new ArnaviBinaryProtocolDecoder(null)); verifyNull(decoder, binary( "ff23f30c45f5c90f0300")); diff --git a/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java b/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java index 3f495731a..92ca5d2b0 100644 --- a/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java @@ -8,7 +8,7 @@ public class ArnaviFrameDecoderTest extends ProtocolTest { @Test public void testDecodeValidPackets() throws Exception { - var decoder = new ArnaviFrameDecoder(); + var decoder = inject(new ArnaviFrameDecoder()); verifyFrame( binary("2441562c563344492c38353136342c3231342c2d312c31392c30303030344634462c30303030303935452c30433030303030322c3836333037313031333034313631382c38393939373031353630333832353236363232462c2a3039"), diff --git a/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java index 9e9047be4..e27367119 100644 --- a/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ArnaviTextProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ArnaviTextProtocolDecoder(null); + var decoder = inject(new ArnaviTextProtocolDecoder(null)); verifyPosition(decoder, buffer( "$AV,V4,999999,12487,2277,203,65534,0,0,193,65535,65535,65535,65535,1,13,80.0,56.1,200741,5950.6773N,03029.1043E,300.0,360.0,121012,65535,65535,65535,SF*6E")); diff --git a/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java index 3376fa3f0..2d8798dff 100644 --- a/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AstraProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AstraProtocolDecoder(null); + var decoder = inject(new AstraProtocolDecoder(null)); verifyPositions(decoder, binary( "4b00700529c0c265976b8202cba9ff00676d864554a9c30000000020073401006436000300030008000000000000a0000100001920c43d00009600428302cba9ff00676d864554aa3e000000002007240100643b000300020008000000000000b0000100001920c43d00009600420f0e")); diff --git a/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java b/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java index 0782c2d34..773a8f7f5 100644 --- a/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java @@ -8,7 +8,7 @@ public class At2000FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new At2000FrameDecoder(); + var decoder = inject(new At2000FrameDecoder()); verifyFrame( binary("01012f00000000000000000000000000003335363137333036343430373439320fad981997ae8e031fe10c0ea7641903ca32c0331df467233d2a9cd886fbeef8"), diff --git a/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java index 77e90ca53..958814e53 100644 --- a/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java @@ -8,7 +8,7 @@ public class AtrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AtrackFrameDecoder(); + var decoder = inject(new AtrackFrameDecoder()); verifyFrame( binary("4052698c032a924f000147027fe5d7425f642e56060f031847bb68cb500719e26752c25bebc11c7fddce2b8ed4eff4ed863b187cc6653b5b1c1fc6803884d21aeeedae2ec6e72781d97e95b965610c1d107e5400cd5a7b7b3b592e676091c6a5893d80af9b3c63ae4de20d6e5bc60440bf2c299fbabfe268039d558e4b8589dd5173c926b7f51b916ba29f21d46ff9170793fe450072d691896e114fddce4fd29f7f2f9b74e41ca83814015e8a00ffd1f9bd475e2a44624e074a009455ab5628e39fce8036a09368cf1d2ba0d2653b979c0a00e9edc82335a56d1ee6071401d468b0f4cd761a743d011401d15b4636015721870dd0500695b2edabeabf2f4a00a514645cc83a739ad165f320c1ed401617a0a2800a2803ffd2faa68a004660aa598e00acd8f4d866d54eab3c7994284881fe11ebf5e68034e8a0086e674850927f0ae2bc4dafa5844659674451d39e49a00e1dae23d76ed67bb72211d109e4d5bd756da3b68a4b755021e30076a00cf31431a064e41e6a19a68d5396518f7a00f1ff008bfe27f31068766dbb7e1a723d3fbbf8d79aeb764748b489662be7ccbbb6820e07d4500734caa727765aa32ac0720e28026b4bb9ed7ccf2594798bb5b2a0f1f8f4a82800a2803fffd3f9b97352ae02e45004c808e4f7a997823bd005e86600618f26b7b4a9cab819fa500767a749b9403cd74162b903de803acd1e3c28aebf4d4c81401d05a4441fad682444738a00b712f2055f03e502802b14c5dffbc2ac106343ed4012a905411e94b40051401fffd4faa6992488980c793d0773400d54676df2f1e8b9e054b400564ebb77750c463b442d2119247f08f53e9401e7da85d6a12cd221d427217a856c60fe15caea9689292f2832bfac8777f3a00e67538ef150ff00665d9b4b95fba4aee46f623fa8ae26fbe24f88b49b87d3b5bd2a12e38ca3950e3d41e7228008be2ac02d423dadc09071c1047e791fcab96d77c79acdf92969279113f1c1cb7e7401876c4c939b8ba73230e5998e49ac4d66ee6bebd796462ddb9f4ed40140a12339e9dea225b1824d0025140051401fffd5f9bc676f6a7ae4af6e280255cf5c7153a7b0a0052d8715bba64bf32f39a00ed74694902bb1d306e65c500763a5afca2baed2"), diff --git a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java index 4a66dbf58..b6b09fc25 100644 --- a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AtrackProtocolDecoder(null); + var decoder = inject(new AtrackProtocolDecoder(null)); verifyNull(decoder, binary( "4052698c032a924f000147027fe5d7425f642e56060f031847bb68cb500719e26752c25bebc11c7fddce2b8ed4eff4ed863b187cc6653b5b1c1fc6803884d21aeeedae2ec6e72781d97e95b965610c1d107e5400cd5a7b7b3b592e676091c6a5893d80af9b3c63ae4de20d6e5bc60440bf2c299fbabfe268039d558e4b8589dd5173c926b7f51b916ba29f21d46ff9170793fe450072d691896e114fddce4fd29f7f2f9b74e41ca83814015e8a00ffd1f9bd475e2a44624e074a009455ab5628e39fce8036a09368cf1d2ba0d2653b979c0a00e9edc82335a56d1ee6071401d468b0f4cd761a743d011401d15b4636015721870dd0500695b2edabeabf2f4a00a514645cc83a739ad165f320c1ed401617a0a2800a2803ffd2faa68a004660aa598e00acd8f4d866d54eab3c7994284881fe11ebf5e68034e8a0086e674850927f0ae2bc4dafa5844659674451d39e49a00e1dae23d76ed67bb72211d109e4d5bd756da3b68a4b755021e30076a00cf31431a064e41e6a19a68d5396518f7a00f1ff008bfe27f31068766dbb7e1a723d3fbbf8d79aeb764748b489662be7ccbbb6820e07d4500734caa727765aa32ac0720e28026b4bb9ed7ccf2594798bb5b2a0f1f8f4a82800a2803fffd3f9b97352ae02e45004c808e4f7a997823bd005e86600618f26b7b4a9cab819fa500767a749b9403cd74162b903de803acd1e3c28aebf4d4c81401d05a4441fad682444738a00b712f2055f03e502802b14c5dffbc2ac106343ed4012a905411e94b40051401fffd4faa6992488980c793d0773400d54676df2f1e8b9e054b400564ebb77750c463b442d2119247f08f53e9401e7da85d6a12cd221d427217a856c60fe15caea9689292f2832bfac8777f3a00e67538ef150ff00665d9b4b95fba4aee46f623fa8ae26fbe24f88b49b87d3b5bd2a12e38ca3950e3d41e7228008be2ac02d423dadc09071c1047e791fcab96d77c79acdf92969279113f1c1cb7e7401876c4c939b8ba73230e5998e49ac4d66ee6bebd796462ddb9f4ed40140a12339e9dea225b1824d0025140051401fffd5f9bc676f6a7ae4af6e280255cf5c7153a7b0a0052d8715bba64bf32f39a00ed74694902bb1d306e65c500763a5afca2baed2")); @@ -111,7 +111,7 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeCustom() throws Exception { - var decoder = new AtrackProtocolDecoder(null); + var decoder = inject(new AtrackProtocolDecoder(null)); decoder.setCustom(true); diff --git a/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java index fbe3ad0a3..368f7ed4c 100644 --- a/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AuroProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AuroProtocolDecoder(null); + var decoder = inject(new AuroProtocolDecoder(null)); verifyPosition(decoder, text( "M0028T0000816398975I357325031465123E00001W*****110620150437000068DA#RD01DA240000000001+100408425+013756121100620152137231112240330004400")); diff --git a/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java index 0be22b333..30152e94c 100644 --- a/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AustinNbProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AustinNbProtocolDecoder(null); + var decoder = inject(new AustinNbProtocolDecoder(null)); verifyPosition(decoder, text( "48666666666;2017-01-01 16:31:01;52,1133308410645;21,1000003814697;310;120;2292;1;ORANGE")); diff --git a/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java index 3e64defdb..8e17d5673 100644 --- a/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class AutoFonProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AutoFonProtocolDecoder(null); + var decoder = inject(new AutoFonProtocolDecoder(null)); verifyNull(decoder, binary( "10556103592310314825728F")); diff --git a/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java index 697ac8a06..7f837451c 100644 --- a/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AutoGradeProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AutoGradeProtocolDecoder(null); + var decoder = inject(new AutoGradeProtocolDecoder(null)); verifyPosition(decoder, text( "(000000001637868324027912356171116A2250.7611N07556.9425E000.9024427197.36\u008eA0000B0000C0000D0000E0000K0000L0000M0000N0000O0000)")); diff --git a/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java index 64a7459ce..51bbd0d8c 100644 --- a/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AutoTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AutoTrackProtocolDecoder(null); + var decoder = inject(new AutoTrackProtocolDecoder(null)); verifyNull(decoder, binary( "f1f1f1f1330c00201007090006de7200000000daa3")); diff --git a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java index 6138711aa..7f41d6b47 100644 --- a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class AvemaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AvemaProtocolDecoder(null); + var decoder = inject(new AvemaProtocolDecoder(null)); verifyAttribute(decoder, text( "1000000000,20190527072358,121.646024,25.062135,0,0,0,0,10,0.0,1,0.02,12.32,0,0,15,2,466-5,10275,0,0.01,65EB812A000104E0,8000001234,NormanChang"), diff --git a/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java index fb1984d87..1da432cea 100644 --- a/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Avl301ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Avl301ProtocolDecoder(null); + var decoder = inject(new Avl301ProtocolDecoder(null)); verifyNull(decoder, binary( "244c0f086058500087335500010d0a")); diff --git a/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java index 6b9c71b0e..ea3b38e7d 100644 --- a/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class B2316ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new B2316ProtocolDecoder(null); + var decoder = inject(new B2316ProtocolDecoder(null)); verifyPositions(decoder, false, text( "{\"imei\":\"866349041783600\",\"data\":[{\"tm\":1631162952,\"wn\":7},{\"tm\":1631158729,\"ic\":\"89883030000059398609\",\"ve\":\"B2316.TAU.U.TH01\"},{\"tm\":1631158805,\"te\":\"312,363\",\"st\":0,\"ba\":3,\"sn\":80},{\"tm\":1631158829,\"ci\":\"505,1,8218,133179149,-108\"},{\"tm\":1631162956,\"wi\":\"101331c17f4f,-74;f46bef7953bb,-81;b09575cff1c8,-86;e2b9e5d61a7a,-88;b0ee7b4dee2f,-88;e0b9e5d61a77,-89;f66bef7953b9,-89;\",\"te\":\"335,366\",\"hr\":58,\"bp\":\"113,73\",\"st\":0,\"ba\":3,\"sn\":60},{\"tm\":1631162968,\"ci\":\"505,1,8218,133179149,-105\"}]}")); diff --git a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java index 544d49967..4117833c0 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class BceProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BceProtocolDecoder(null); + var decoder = inject(new BceProtocolDecoder(null)); verifyNull(decoder, binary( "3ab90b71bc1503000300c10bff11")); diff --git a/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java index 3fdac8479..2fb93f2a9 100644 --- a/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class BlackKiteProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BlackKiteProtocolDecoder(null); + var decoder = inject(new BlackKiteProtocolDecoder(null)); verifyNull(decoder, binary( "01150003313131313131313131313131313131209836055605BA")); diff --git a/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java index 4e74adf38..1de542e24 100644 --- a/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class BlueProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BlueProtocolDecoder(null); + var decoder = inject(new BlueProtocolDecoder(null)); verifyAttribute(decoder, binary( "AA0056860080E3E79E0C811F80000114020207170520011F00407F8005EE1938113B270000000000000000140202071705005AC7A621121F0002000100B7000080110000000000001A3A0000000001F400000000000078"), diff --git a/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java index 5b639e12b..0a19eb3b0 100644 --- a/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class BoxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BoxProtocolDecoder(null); + var decoder = inject(new BoxProtocolDecoder(null)); verifyNull(decoder, text( "H,BT,358281002435893,081028142432,F5813D19,6D6E6DC2")); diff --git a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java index 6fb14b902..fbb530e7f 100644 --- a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class C2stekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new C2stekProtocolDecoder(null); + var decoder = inject(new C2stekProtocolDecoder(null)); verifyPosition(decoder, text( "PA$867965024889327$D#220222#135059#0#+37.98995#+23.85141#0.00#69.2#0.0#0000#000#8#00#sz-w1001#B2600$AP")); diff --git a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java index 79d27e2ab..1a8431f23 100644 --- a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CalAmpProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CalAmpProtocolDecoder(null); + var decoder = inject(new CalAmpProtocolDecoder(null)); verifyPosition(decoder, binary( "830547643586340101010400105f9c39ba5f9c302eeb36d5bddf39df700000000000000000003400040321ff9f4f0087080200001c30783330304544383946333335303139303030303030343637450d0a")); diff --git a/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java index dd96c2585..d12d4aa9f 100644 --- a/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CarTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CarTrackProtocolDecoder(null); + var decoder = inject(new CarTrackProtocolDecoder(null)); verifyNull(decoder, text( "$$020040????????&A0000")); diff --git a/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java index b1fe69bac..71137cacf 100644 --- a/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CarscopProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CarscopProtocolDecoder(null); + var decoder = inject(new CarscopProtocolDecoder(null)); verifyNull(decoder, text( "*170821223045UB00HSO")); diff --git a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java index f90fbe5ba..1add623b7 100644 --- a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class CastelProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CastelProtocolDecoder(null); + var decoder = inject(new CastelProtocolDecoder(null)); verifyAttribute(decoder, binary( "40403a00043231334744503230313830323133343300000000a002000001000001012011004d414c43333831434d4b4d353637313438c8fc0d0a"), diff --git a/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java index fe8586068..4022d688b 100644 --- a/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CautelaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CautelaProtocolDecoder(null); + var decoder = inject(new CautelaProtocolDecoder(null)); verifyPosition(decoder, text( "20,010907000000,14,02,18,16.816667,96.166667,1325,S,*2E")); diff --git a/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java index 04a0f74d5..c266dd1f4 100644 --- a/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java @@ -8,7 +8,7 @@ public class CellocatorFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CellocatorFrameDecoder(); + var decoder = inject(new CellocatorFrameDecoder()); verifyFrame( binary("4D4347500BA9880B00C80A7E003800000000000806000001210A14000613000000000D4457A5F71442AC02E80300000100040707000011171408060E1C08000100000200020000FD"), diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java index 3ae5350f2..7e96b073b 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CellocatorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CellocatorProtocolDecoder(null); + var decoder = inject(new CellocatorProtocolDecoder(null)); verifyPosition(decoder, binary( "4D43475000856308000004B2DE1F04009E00200100000000696CF7AB002F1A00000000000000325C000402069BFDE70857E22502F41C000036000000DF0B0932100B09DC0719")); diff --git a/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java index a7ed0e754..835ab5fe5 100644 --- a/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CguardProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CguardProtocolDecoder(null); + var decoder = inject(new CguardProtocolDecoder(null)); verifyNull(decoder, text( "IDRO:354868050655283")); diff --git a/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java index 07d6368ab..0c1fc1f5d 100644 --- a/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class CityeasyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CityeasyProtocolDecoder(null); + var decoder = inject(new CityeasyProtocolDecoder(null)); verifyNotNull(decoder, binary( "545400853575570249020100033b3430342c34352c31303638312c31313632312c33352c31303638312c31313632322c32332c31303638312c32383938332c32332c31303638312c31313632332c32312c31303638312c32333338312c31372c31303638312c32323538332c31372c31303638312c32363434312c31330000000d352e0d0a")); diff --git a/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java index 2924d2c4d..6ac2ae01d 100644 --- a/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ContinentalProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ContinentalProtocolDecoder(null); + var decoder = inject(new ContinentalProtocolDecoder(null)); verifyPosition(decoder, binary( "5356003216001eb48505025b4001e90f7f18ce0f00522200400001015b4001e9000e820100000c24000100014e0400736a7a"), diff --git a/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java index 1e3023b39..f95bfb54d 100644 --- a/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CradlepointProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CradlepointProtocolDecoder(null); + var decoder = inject(new CradlepointProtocolDecoder(null)); verifyPosition(decoder, text( "356526070063940,0,4337.19009,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,")); diff --git a/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java index 6236410b3..c63775858 100644 --- a/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java @@ -8,7 +8,7 @@ public class DingtekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DingtekFrameDecoder(); + var decoder = inject(new DingtekFrameDecoder()); verifyFrame( binary("383030303031303131453032383830303138303030303030303030313545303038303545433430303031313836383832323034303130343433303831"), diff --git a/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java index 8b3d07c22..7e5f68e05 100644 --- a/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DingtekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DingtekProtocolDecoder(null); + var decoder = inject(new DingtekProtocolDecoder(null)); verifyPosition(decoder, text( "800001011e0692001a00000000016e008027c40000186962703655111781")); diff --git a/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java index 4492b3ed0..3faccd7ea 100644 --- a/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DishaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DishaProtocolDecoder(null); + var decoder = inject(new DishaProtocolDecoder(null)); verifyPosition(decoder, text( "$A#A#864161028848856#A#053523#010216#2232.7733#N#08821.1940#E#002.75#038.1#09#00.8#1800#0#000#0000#9999#11.7#285.7#0001*")); diff --git a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java index 31d0efa12..99760546f 100644 --- a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class DmtHttpProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DmtHttpProtocolDecoder(null); + var decoder = inject(new DmtHttpProtocolDecoder(null)); verifyAttributes(decoder, request(HttpMethod.POST, "/", buffer("{\"date\":\"2021-12-12T16:04:52Z\",\"device\":{\"sn\":\"416581\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278612797427\",\"imei\":\"351358810439486\"},\"sqn\":1549,\"reason\":42,\"counters\":[{\"id\":0,\"val\":5304},{\"id\":3,\"val\":3200},{\"id\":4,\"val\":5066},{\"id\":128,\"val\":1},{\"id\":129,\"val\":8},{\"id\":130,\"val\":0},{\"id\":131,\"val\":0},{\"id\":132,\"val\":0},{\"id\":134,\"val\":1},{\"id\":138,\"val\":0},{\"id\":139,\"val\":36},{\"id\":142,\"val\":1629023},{\"id\":145,\"val\":0},{\"id\":146,\"val\":1}]}"))); diff --git a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java index 82a4cd5ff..9c14a1ebe 100644 --- a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DmtProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DmtProtocolDecoder(null); + var decoder = inject(new DmtProtocolDecoder(null)); verifyNull(decoder, binary( "0255003300001b00003335333232393032373533393235310038393931353030303030303030313330343539340000000403041910780603")); diff --git a/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java index 0215973e8..b9e3da67d 100644 --- a/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DolphinProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DolphinProtocolDecoder(null); + var decoder = inject(new DolphinProtocolDecoder(null)); verifyPositions(decoder, binary( "ababff8f0300000100000100e03c0b86c70e03005c0f0000ab4cd12d0aa9010d0d7f0e4215f6fe6c421d00b0ce4420122daa9a9042359a99f9413806455e53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662404801010ce41bb8f4cc2ad801fe98f3030893dd9a010001019299f303155400000007b401000000000072ac01b99401f8de8a0adc03900e0049000003004bfa010aa7010d4f7f0e421505ff6c421dcd1cce4420112d3ef984423552b89e413806456053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4201010ce41bd8f4cc2a20ff98f3030193dd9a010001019399f30315420000000000000000000072ad018f950181df8a0aee03cd0d004b000003004bfa010aa7010da67f0e42154fff6c421d3393cd4420112d073c9942358fc2df413806456253fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4c010111f51d88f5cc2a308199f3030293dd9a010001019599f303154c0000000000000000000072ad01ef95018bdf8a0aee03d30d004a000003004bfa010aa9010dfd800e421525006d421d3373d04420102da5b7aa4235ec51c4413806456853fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405501010ef01db0f6cc2aa8018899f3030793dd9a010001019c99f3031555000000068a010000000000739d01df9501acdf8a0ac0028a150031000003004bfa010aa8010d3b830e421561016d421dcddcd04420102d8edda94235cdccbe413806457353fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f5401010ef01db8f8cc2a88029499f3030c93dd9a01000101a899f303155500000004480000000000728a018f9501e5df8a0aa9018d280015000003004bfa010aa8010ddd850e4215b3026d421dcd3cd04420112d2e9ba942359a99af413806458053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f5401010df01df0facc2ab802a199f3030d93dd9a01000101b599f303155500000005760000000000728b01f59401a2e08a0a9b01c12b0018000003004bfa010aa9010d4a870e421554036d421d66d6cf4420112d5f29a842355c8faa413806458753fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405401010dea1d98fccc2aa801a899f3030793dd9a01000101bc99f303155400000007a4010000000000719701b29401bae08a0a9202be180026000003004bfa010aa7010da7870e421591036d421d33d3cf4420112d6329a942353333a7413806458953fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e5401010df51dc8fccc2a30aa99f3030293dd9a01000101be99f3031554000000022c0000000000719901db9401c3e08a0aae02a016002b000003004bfa010aa7010d1a880e4215b6036d421d33e3cf4420112ddc45aa423514aea3413806458b53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e5501010df51df8fccc2a30ac99f3030293dd9a01000101c099f303155500000002320000000000719e01f69401d1e08a0a9f02b3170031000003004bfa010aa8010d50890e42154d046d421d3363d04420102da0b7a94235d7a3a2413806459253fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f5401010edf1d88fecc2a9001b399f3030793dd9a01000101c799f303155400000000000000000000729a01e69501f7e08a0ab0028e16002d000003004bfa010aa9010d188c0e421573056d421d00c0ce4420102d300c84423514ae7741380645a053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624042010110da1dd080cd2ac802c199f3030e93dd9a01000101d599f303155500000009e2010000000000729801b19501afe18a0a97029018002a000003004bfa010aa7010d528c0e42159d056d421d3313cf4420102dfec98c423552b8c241380645a053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e46010110da1df080cd2a20c299f3030193dd9a01000101d699f303154600000000000000000000729701df9501b8e18a0aa002b9170029000003004bfa010aa9010d198f0e42159e066d421d9a49d04420112dfae6a642359a999941380645ad53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624053010111e51da883cd2ab802cf99f3030d93dd9a01000101e399f30315540000000ca4020000000000729601c49501f1e18a0a9102dc180028000003004bfa010aa7010da68f0e4215e9066d421d9a19d044200f2d83dda74235ec519441380645b153fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e53010111e51df083cd2a48d299f3030393dd9a01000101e699f303155300000003400000000000729701de950183e28a0a8e02ff180028000003004bfa010aa7010d40900e42151a076d421d33c3cf4420102d717e9b423548e15e41380645b453fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4d010110e51db884cd2a48d599f3030393dd9a01000101e999f303154d00000003420000000000729801bf950191e28a0a9a02f117002a000003004bfa010aa7010d5f900e42153c076d421d66c6cf44200f2de3028d4235713daa41380645b553fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e46010110da1dc884cd2a10d699f3030193dd9a01000101ea99f303154600000001120000000000729901bf950191e28a0a98029318002b000003004bfa010aa7010dae900e42153d076d421d9ad9cf44200f2d324fa342357b144241380645b653fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e51010110da1de884cd2a20d799f3030193dd9a01000101eb99f303155100000000000000000000729b01a5950196e28a0aa2029b17002c000003004bfa010aa7010d08910e42157e076d421d33b3cf4420102d51b79a42357b14b241380645b853fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4d010110da1d9885cd2a30d999f3030293dd9a01000101ed99f3031552000000022c0000000000729b01ca95019be28a0ab602e815002f000003004bfa010aa9010d3b930e42153f086d421d9a99d044200f2d5a3ca9423552b88441380645c153fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624054010110f51d9087cd2af801e499f3030b93dd9a01000101f899f30315540000000bfa010000000000729901cf9501cee28a0ac502f814002e000003004bfa010aa9010df1950e421558096d421d6646d24420102da3a4a842357b149441380645cf53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405401010eea1dc889cd2ab802f199f3030d93dd9a01000101859af303155500000008be010000000000729901c7950190e38a0a9c02da17002c000003004bfa010aa9010dcf970e4215260a6d421d6676d34420112d653cab423552b89e41380645d853fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405501010efa1ba08bcd2ad801fa99f3030993dd9a010001018e9af303155600000007a8010000000000729e01bb9501bae38a0ac00284150031000003004bfa010aa8010de89a0e4215510b6d421d00a0d44420112d1aaea74235cdcc6841380645e653fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f53010110f51d808ecd2ae002899af3030f93dd9a010001019d9af30315550000000460000000000073a401e59501fce38a0a9003e510003e000003004bfa010aa9010d6b9c0e4215b00b6d421d00b0d44420112dd46bac423585eb0541380645ed53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624056010110ea1da88fcd2aa801919af3030893dd9a01000101a59af303155600000008a801000000000073a201a19501a1e48a0a8103ce110038000003004bfa01")); diff --git a/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java index fc18b0560..7e3ec0706 100644 --- a/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Dsf22FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Dsf22FrameDecoder(); + var decoder = inject(new Dsf22FrameDecoder()); verifyFrame( binary("4642000101A8EE5F0ECA5FF421B33F524E32610401"), diff --git a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java index 4089c208c..2e52b950d 100644 --- a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Dsf22ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Dsf22ProtocolDecoder(null); + var decoder = inject(new Dsf22ProtocolDecoder(null)); verifyPositions(decoder, binary( "4642a82d01c8f6aa1af1792c0c1411eb61001e0000")); diff --git a/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java b/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java index 46f32a8ae..f74a40d13 100644 --- a/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java @@ -8,7 +8,7 @@ public class DualcamFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DualcamFrameDecoder(); + var decoder = inject(new DualcamFrameDecoder()); verifyFrame( binary("000000050001403a4abaa31444000400"), diff --git a/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java index 3dd11bdf7..a61f20c13 100644 --- a/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DualcamProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DualcamProtocolDecoder(null); + var decoder = inject(new DualcamProtocolDecoder(null)); verifyNull(decoder, binary( "000000050001403a4abaa31444000400")); diff --git a/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java index 368f8b4ac..1cdd82664 100644 --- a/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DwayProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DwayProtocolDecoder(null); + var decoder = inject(new DwayProtocolDecoder(null)); verifyPosition(decoder, text( "AA55,36,10024,1,171025,161055,36.0294,-79.7881,201, 2.5,111,1000,0000,00000,3578,0,0,0,D")); diff --git a/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java index 5fda7fb28..ef319449e 100644 --- a/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EasyTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EasyTrackProtocolDecoder(null); + var decoder = inject(new EasyTrackProtocolDecoder(null)); verifyNotNull(decoder, text( "*ET,354522180593498,JZ,0,20222,262,724,4#")); diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java index c1cc3c39a..ec1467c09 100644 --- a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EelinkProtocolDecoder(null); + var decoder = inject(new EelinkProtocolDecoder(null)); verifyPositions(decoder, binary( "454c029249a50354679090044671676712004321315f3cf43503fc94d3760c79328a0129000000000a01f9000190330905580d2e046f118a04ec00000000ccc7086c02fe000000000000000000000000000000000000676712004321325f3cf43e03fc94d3760c79328a0129000000000901f9000190330905580d2e046f117b04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321335f3cf44703fc94d3760c79328a0129000000000901f9000190330905580d2e046f117f04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321345f3cf45303fc94d3760c79328a0129000000000901f9000190330905580d2e046f119d04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321355f3cf45c03fc94d3760c79328a0129000000000801f9000190330905580d2e046f11a304ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321365f3cf46603fc94d3760c79328a0129000000000801f9000190330905580d2e046f118804df00000000ccc7086d02ff000000000000000000000000000000000000676712004321375f3cf47103fc94d3760c79328a0129000000000901f9000190330905580d2e046f119704ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321385f3cf47a03fc94d3760c79328a0129000000000901f9000190330905580d2e046f118204ec00000000ccc7086e0300000000000000000000000000000000000000676712004321395f3cf48303fc94d3760c79328a0129000000000901f9000190330905580d2e046f117604df00000000ccc7086e0300000000000000000000000000000000000000")); diff --git a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java index a1acb1e9d..dde71d1e7 100644 --- a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java @@ -8,7 +8,7 @@ public class EgtsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EgtsFrameDecoder(); + var decoder = inject(new EgtsFrameDecoder()); verifyFrame( binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"), diff --git a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java index dcf70bcae..0f5a40605 100644 --- a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EgtsProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeWithObjectId() throws Exception { - var decoder = new EgtsProtocolDecoder(null); + var decoder = inject(new EgtsProtocolDecoder(null)); verifyNull(decoder, binary( "0100020b002300020001871c00020000010105190000ab0800006247396e615734366347467a63336476636d513daadf")); @@ -31,7 +31,7 @@ public class EgtsProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeWithAuth() throws Exception { - var decoder = new EgtsProtocolDecoder(null); + var decoder = inject(new EgtsProtocolDecoder(null)); verifyNull(decoder, binary( "0100010b002200c06401f21700c1640171360d00010101140071360d000238363539303500000000000000000047fc")); diff --git a/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java index 14e982e39..2d2a211c3 100644 --- a/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EnforaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EnforaProtocolDecoder(null); + var decoder = inject(new EnforaProtocolDecoder(null)); verifyNull(decoder, binary( "000A08002020202020303131303730303030353730323637")); diff --git a/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java index 4afa5921f..0134e8052 100644 --- a/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EnnfuProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EnnfuProtocolDecoder(null); + var decoder = inject(new EnnfuProtocolDecoder(null)); verifyPosition(decoder, text( "Ennfu:354679095321652,041504.00,A,3154.86654,N,11849.08737,E,0.053,,080121,20,3.72,21.4,V0.01")); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 0809a1e9a..50db6c743 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EnvotechProtocolDecoder(null); + var decoder = inject(new EnvotechProtocolDecoder(null)); verifyPosition(decoder, text( "$80IVM,03,E002215,E002215,110422061936,672763902,126423,0180,000000,00018600,0.0000'11042206193710406325S03966094E000118*42D6#")); diff --git a/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java index d0d9e3c41..2d9b19b70 100644 --- a/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EsealProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EsealProtocolDecoder(null); + var decoder = inject(new EsealProtocolDecoder(null)); verifyPosition(decoder, text( "##S,eSeal,1000821,256,3.0.6,Normal,34,2017-08-31,08:14:40,15,A,25.708828N 100.372870W,10,0,Close,0.71,0:0:3:0,3.8,-73,E##")); diff --git a/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java b/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java index c3926c8d7..f808cd4a8 100644 --- a/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java @@ -8,7 +8,7 @@ public class EskyFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EskyFrameDecoder(); + var decoder = inject(new EskyFrameDecoder()); verifyNull( decoder.decode(null, null, binary("00"))); diff --git a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java index ace55f934..678007f5c 100644 --- a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class EskyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EskyProtocolDecoder(null); + var decoder = inject(new EskyProtocolDecoder(null)); verifyAttribute(decoder, text( "ET;0;860337031066546;R;9+200717114059+41.32053+19.80761+0.30+0+0x2+8+40381744+0+1409+11"), diff --git a/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java index 29d11e02f..36a26bbe3 100644 --- a/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ExtremTracProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ExtremTracProtocolDecoder(null); + var decoder = inject(new ExtremTracProtocolDecoder(null)); verifyPosition(decoder, text( "$GPRMC,862106020628733,050859.000,A,1404.8573,N,08710.9967,W,0.00,0,080117,0,,00C8,00218,99,,,,,,0.00")); diff --git a/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java index 32657b277..417c49de5 100644 --- a/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java @@ -8,7 +8,7 @@ public class FifotrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FifotrackFrameDecoder(); + var decoder = inject(new FifotrackFrameDecoder()); verifyFrame( binary("24243132362c3836393436373034393239303738372c324138432c4130312c2c3139303431333135333235342c412c2d31352e3132373836382c33392e3236323530362c302c3136322c3431352c38303937323234332c302c303030302c30302c302c3634337c337c353141467c424632462c3141337c3446367c3833327c302c312c2a3534"), diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java index 6480d1dc4..ec08b432c 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FifotrackProtocolDecoder(null); + var decoder = inject(new FifotrackProtocolDecoder(null)); verifyPosition(decoder, buffer( "$$95,866104023192332,1,A03,,210414055249,460|0|25FC|104C,4.18,100,000F,0,A,2,9,22.643175,114.018150*75")); diff --git a/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java index 88fdb0959..c794c9094 100644 --- a/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class FlespiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlespiProtocolDecoder(null); + var decoder = inject(new FlespiProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/", buffer("[{\"position.speed\":0,\"position.latitude\":53.90573,\"time.valid.status\":true,\"timestamp\":1506956075,\"position.satellites\":10,\"message.buffered.status\":false,\"business.mode.status\":true,\"gps.status\":true,\"position.longitude\":27.455848,\"position.direction\":0,\"ident\":\"605630\"},{\"siren.status\":false,\"business.mode.status\":true,\"position.satellites\":8,\"timestamp\":1506695785,\"led.status\":false,\"position.latitude\":53.905569,\"position.longitude\":27.455986,\"position.speed\":0,\"gradual.stop.status\":false,\"position.direction\":262.643854,\"hardware.version.enum\":223,\"vehicle.mileage\":160,\"message.buffered.status\":false,\"blinkers.status\":false,\"ident\":\"605630\",\"position.altitude\":233.48,\"immobilizer.status\":false}]"))); diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index c819cd8bf..ffb8eb3a9 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlexApiProtocolDecoder(null); + var decoder = inject(new FlexApiProtocolDecoder(null)); verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021113001/motion/info\",\"payload\":{\"motion.ts\":1641885877,\"motion.ax\":0.006344,\"motion.ay\":0.289384,\"motion.az\":-0.939156,\"motion.gx\":0.420000,\"motion.gy\":0.420000,\"motion.gz\":-0.280000}}xx")); diff --git a/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java index 3e988ba4f..ed44fc62e 100644 --- a/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FlexCommProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlexCommProtocolDecoder(null); + var decoder = inject(new FlexCommProtocolDecoder(null)); verifyPosition(decoder, text( "7E00865067022408382201705302358271024932258006712785200700022601010224100040002C5002A2210001000000010012342107")); diff --git a/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java index 8763887a5..6b289396d 100644 --- a/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FlexibleReportProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlexibleReportProtocolDecoder(null); + var decoder = inject(new FlexibleReportProtocolDecoder(null)); verifyPosition(decoder, binary( "7d010015875000013001001028fd98991830002e7fffffff0c28fd989903f6540a07f250ed00000f02f2140f5ea20000000000000202d4000a1f8b0100000708ffff")); diff --git a/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java index 0c1c18a0c..6e5ebf4cf 100644 --- a/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class FlextrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlextrackProtocolDecoder(null); + var decoder = inject(new FlextrackProtocolDecoder(null)); verifyNull(decoder, text( "-1,LOGON,7000000123,8945000000")); diff --git a/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java index 439a5553a..8e62c878e 100644 --- a/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FoxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FoxProtocolDecoder(null); + var decoder = inject(new FoxProtocolDecoder(null)); verifyPosition(decoder, text( "")); diff --git a/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java index c8f7a444b..1163b4e04 100644 --- a/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FreedomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FreedomProtocolDecoder(null); + var decoder = inject(new FreedomProtocolDecoder(null)); verifyPosition(decoder, text( "IMEI,353358011714362,2014/05/22, 20:49:32, N, Lat:4725.9624, E, Lon:01912.5483, Spd:5.05"), diff --git a/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java index 6a7a15397..a7ce042e5 100644 --- a/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FreematicsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FreematicsProtocolDecoder(null); + var decoder = inject(new FreematicsProtocolDecoder(null)); verifyPositions(decoder, text( "M0ZR4X0#0:204391,11:140221,10:8445000,A:49.215920,B:18.737755,C:410,D:0,E:208,24:1252,20:0;0;0,82:47*B5")); diff --git a/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java b/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java index b8eb3908e..a101ef45d 100644 --- a/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java @@ -8,7 +8,7 @@ public class FutureWayFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FutureWayFrameDecoder(); + var decoder = inject(new FutureWayFrameDecoder()); verifyFrame( binary("343130303030303039424130303030344750533a562c3230303930323039333333332c302e3030303030304e2c302e303030303030452c302e3030302c302e3030300d0a574946493a332c317c39302d36372d31432d46372d32312d36437c353226327c38302d38392d31372d43362d37392d41307c353426337c34302d46342d32302d45462d44442d32417c35380d0a4c42533a3436302c302c34363437353036362c36390d0a36413432"), diff --git a/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java index fbb0a2aba..e529d5c90 100644 --- a/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FutureWayProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FutureWayProtocolDecoder(null); + var decoder = inject(new FutureWayProtocolDecoder(null)); verifyNull(decoder, text( "410000003F2000020,IMEI:354828100126461,battery level:6,network type:7,CSQ:236F42")); diff --git a/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java index 0d3199eab..a5aba3513 100644 --- a/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java @@ -10,7 +10,7 @@ public class GalileoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GalileoFrameDecoder(); + var decoder = inject(new GalileoFrameDecoder()); assertEquals( binary("011780011102e603383633353931303238393630323437043200801c"), diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index 66b375b8a..d76fc5895 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GalileoProtocolDecoder(null); + var decoder = inject(new GalileoProtocolDecoder(null)); verifyPositions(decoder, binary( "011801018202130338363833343530333230343234323604640010a406207caa9f5b300c830a7901ca0ec802330000000034b802350540003e41703f422b1043234504004600e09000000000a000a100a200a300a400a500a600a700a800a900aa00ab00ac00ad00ae00af00b00000b10000b20000b30000b40000b50000b60000b70000b80000b90000c000000000c100000000c200000000c300000000c400c500c600c700c800c900ca00cb00cc00cd00ce00cf00d000d100d200d4d3140000d60000d70000d80000d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000f400000000f500000000f600000000f700000000f800000000f9000000008960")); diff --git a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java index 24686e220..bfb33de22 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java @@ -17,7 +17,7 @@ public class GatorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GatorProtocolDecoder(null); + var decoder = inject(new GatorProtocolDecoder(null)); verifyAttributes(decoder, binary( "242480002600341cad190917022021812497260280594200000000c047010000135400009bb600ff00b90d")); diff --git a/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java index 382c974ce..67a730f97 100644 --- a/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GenxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GenxProtocolDecoder(null); + var decoder = inject(new GenxProtocolDecoder(null)); decoder.setReportColumns("28,2,3,4,13,17,10,23,27,11,7,8,46,56,59,70,74,75,77,89,90,93,99,107,112,113,114,176,175,178,181,182"); diff --git a/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java index 50f993839..31ae1d5e8 100644 --- a/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gl100ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl100ProtocolDecoder(null); + var decoder = inject(new Gl100ProtocolDecoder(null)); verifyPosition(decoder, text( "+RESP:GTLGL,359464030492644,1,2,1,0,0.4,0,299.7,1,5.455551,51.449776,20160311083229,0204,0016,03EC,BD94,00,0036,0102090501")); diff --git a/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java index b8ce8af5d..cad70c35b 100644 --- a/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl200BinaryProtocolDecoder(null); + var decoder = inject(new Gl200BinaryProtocolDecoder(null)); verifyPosition(decoder, binary( "2b4556542d00fc1fbf0063450102020956325403000343056437f8220700000200000000010000160100f2007eff75a1f0025c6b1a07e1080108241a02680003189c1ac500000000000002100800000000000000000007e1080108241a19e24e4e0d0a")); diff --git a/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java index 17eed8a59..51816222d 100644 --- a/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java @@ -10,7 +10,7 @@ public class Gl200FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl200FrameDecoder(); + var decoder = inject(new Gl200FrameDecoder()); assertEquals( binary("2b4c474e00ff0026fe110b07020106563454040d054905000007e4031911213905083abd0d0a"), diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 429ee15c7..6857feddc 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl200TextProtocolDecoder(null); + var decoder = inject(new Gl200TextProtocolDecoder(null)); verifyPosition(decoder, buffer( "+RESP:GTFRI,5E0100,861971050039361,,,,10,1,1,10.4,140,196.9,-80.709946,35.016525,20220302220944,0310,0260,1CE9,52A1,00,0.0,,,,,420000,,,,20220302220948,1B0B$")); diff --git a/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java index 3f5296f4b..e244a835d 100644 --- a/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GlobalSatProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GlobalSatProtocolDecoder(null); + var decoder = inject(new GlobalSatProtocolDecoder(null)); verifyNull(decoder, text( "GSh,131826789036289,3,M,ea04*3d")); diff --git a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java index 1dd5c2542..f0ba813ca 100644 --- a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GlobalstarProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GlobalstarProtocolDecoder(null); + var decoder = inject(new GlobalstarProtocolDecoder(null)); verifyNull(decoder, request(HttpMethod.POST, "/", buffer( "\n", diff --git a/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java index 8bd5e2bd5..592c2de91 100644 --- a/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GnxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GnxProtocolDecoder(null); + var decoder = inject(new GnxProtocolDecoder(null)); verifyPosition(decoder, text( "$GNX_MIF,865733022354161,143,0,172642,180316,172642,180316,1,13.034581,N,080.234521,E,0,05396274,ROUTE_2#########,Deo ############,GNX04008,B0*")); diff --git a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java index bb79f4f25..71ffbb587 100644 --- a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GoSafeProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GoSafeProtocolDecoder(null); + var decoder = inject(new GoSafeProtocolDecoder(null)); verifyPositions(decoder, false, text( "*GS06,357330050846344,RST#")); diff --git a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java index 373858c79..a6e3f2d69 100644 --- a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GotopProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GotopProtocolDecoder(null); + var decoder = inject(new GotopProtocolDecoder(null)); verifyNull(decoder, text( "")); diff --git a/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java index f6524f82b..cb75b4035 100644 --- a/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java @@ -10,7 +10,7 @@ public class Gps056FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gps056FrameDecoder(); + var decoder = inject(new Gps056FrameDecoder()); assertEquals( binary("242435314750534c5f30323836323436323033333738323934361905110f160b0b7710584e1cbd1b9b4500005b100300fb0a071700ffff23"), diff --git a/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java index 01fa98ba4..ac3738644 100644 --- a/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gps056ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gps056ProtocolDecoder(null); + var decoder = inject(new Gps056ProtocolDecoder(null)); verifyNull(decoder, buffer( "$$25LOGN_118624620337829462.1#")); diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java index 79dc8ab7b..425fcd8ae 100644 --- a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gps103ProtocolDecoder(null); + var decoder = inject(new Gps103ProtocolDecoder(null)); verifyPosition(decoder, text( "imei:864035050002451,tracker,201223064947,,F,064947,A,1935.70640,N,09859.94436,W,0.025,;")); diff --git a/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java index c935fb3c2..a1f81b329 100644 --- a/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GpsGateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GpsGateProtocolDecoder(null); + var decoder = inject(new GpsGateProtocolDecoder(null)); verifyPosition(decoder, text( "$FRCMD,0097,_SendMessage,,7618.51990,S,4002.26182,E,350.0,1.08,0.0,250816,183522.000,0*7F")); diff --git a/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java index c0b4966a8..bc7910779 100644 --- a/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GpsMarkerProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GpsMarkerProtocolDecoder(null); + var decoder = inject(new GpsMarkerProtocolDecoder(null)); verifyPosition(decoder, text( "$GM23D863071014445404T260816142611N55441051E037325071033063C0530304#")); diff --git a/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java index 7170718f6..d1326515f 100644 --- a/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GpsmtaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GpsmtaProtocolDecoder(null); + var decoder = inject(new GpsmtaProtocolDecoder(null)); verifyPosition(decoder, text( "3085a94ef459 1446536867 49.81621 24.054207 1 0 22 0 10 12 24 0 0")); diff --git a/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java b/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java index b4e24f961..a61e708f7 100644 --- a/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java @@ -10,7 +10,7 @@ public class GranitFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GranitFrameDecoder(); + var decoder = inject(new GranitFrameDecoder()); assertEquals( binary("2b525243427e1a003e2934757c57b8b03c38d279b4e61e9bd7006b000000001c00002a4533"), diff --git a/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java index 7fd5ffe0e..d2e181e09 100644 --- a/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GranitProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GranitProtocolDecoder(null); + var decoder = inject(new GranitProtocolDecoder(null)); verifyPositions(decoder, binary( "2b444441547e8400c500040130050c43495808002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000014002a37420d0a")); diff --git a/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java index 68c9b8219..ce2768448 100644 --- a/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gs100ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gs100ProtocolDecoder(null); + var decoder = inject(new Gs100ProtocolDecoder(null)); verifyNull(decoder, binary( "474C490F383632343632303332353036373030133839333831303131363039313838343837323546084657312E302E3236")); diff --git a/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java index 9d36ef346..25f59a948 100644 --- a/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gt02ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt02ProtocolDecoder(null); + var decoder = inject(new Gt02ProtocolDecoder(null)); verifyAttributes(decoder, binary( "6868150000035889905895258400831c07415045584f4b210d0a")); diff --git a/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java index 059674398..a9d011277 100644 --- a/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Gt06FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt06FrameDecoder(); + var decoder = inject(new Gt06FrameDecoder()); verifyFrame( binary("787803691604130318491475905BD30E25001E10BBF7635D14759006E626560501CC0028660F213228660F1F2828660EA81E286610731428660F20140D0A"), diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index b65b6709e..5b355e4f5 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt06ProtocolDecoder(null); + var decoder = inject(new Gt06ProtocolDecoder(null)); verifyNull(decoder, binary( "787805120099abec0d0a")); diff --git a/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java index 24addc8b4..48c4306d6 100644 --- a/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gt30ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt30ProtocolDecoder(null); + var decoder = inject(new Gt30ProtocolDecoder(null)); verifyPosition(decoder, text( "$$005D3037811014 9955102834.000,A,3802.8629,N,02349.7163,E,0.00,,060117,,*13|1.3|26225BD")); diff --git a/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java b/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java index 2294b773b..c61c0f0c9 100644 --- a/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java @@ -10,7 +10,7 @@ public class H02FrameDecoderTest extends ProtocolTest { @Test public void testDecodeShort() throws Exception { - var decoder = new H02FrameDecoder(0); + var decoder = inject(new H02FrameDecoder(0)); assertEquals( binary("2a48512c3335353438383032303131333931312c56312c3031323934352c412c353233312e37393238332c4e2c30313332342e31303731382c452c302e30352c302c3137303231372c464646464646464623"), @@ -37,7 +37,7 @@ public class H02FrameDecoderTest extends ProtocolTest { @Test public void testDecodeLong() throws Exception { - var decoder = new H02FrameDecoder(0); + var decoder = inject(new H02FrameDecoder(0)); assertEquals( binary("24410600082621532131081504419390060740418306000000fffffbfdff0015060000002c02dc0c000000001f"), @@ -48,7 +48,7 @@ public class H02FrameDecoderTest extends ProtocolTest { @Test public void testDecodeAlternative() throws Exception { - var decoder = new H02FrameDecoder(0); + var decoder = inject(new H02FrameDecoder(0)); assertEquals( binary("2a48512c343230363131393133302c4e42522c3130323430332c3233382c312c302c372c313131312c323236342c36332c313131312c323236352c35382c313131312c323236362c35302c313131312c333133352c33372c313131312c3630352c33332c313131312c343932302c33302c313131312c3630372c32382c3131303131372c46464646444646462c3623"), diff --git a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java index ad5f82176..278931466 100644 --- a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new H02ProtocolDecoder(null); + var decoder = inject(new H02ProtocolDecoder(null)); verifyPosition(decoder, buffer( "*HQ,5905101893,V1,105759,A,37573392,S,145037022,E,000.00,173,280122,FF7FFBFF,,,9059e2c,8232,4#")); @@ -270,7 +270,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeStatus() throws Exception { - var decoder = new H02ProtocolDecoder(null); + var decoder = inject(new H02ProtocolDecoder(null)); verifyAttribute(decoder, buffer( "*HQ,2705171109,V1,213324,A,5002.5849,N,01433.7822,E,0.00,000,140613,FFFFFFFF#"), diff --git a/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java index 9d80940ea..9d26d56c3 100644 --- a/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HaicomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HaicomProtocolDecoder(null); + var decoder = inject(new HaicomProtocolDecoder(null)); verifyPosition(decoder, text( "$GPRS012497007097169,T100001,150618,230031,5402267400332464,0004,2014,000001,,,1,00#V040*"), diff --git a/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java index 192aa3010..8fe4d2c8b 100644 --- a/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HomtecsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HomtecsProtocolDecoder(null); + var decoder = inject(new HomtecsProtocolDecoder(null)); verifyNull(decoder, text( "MDS0001_R6d1821f7,170323,143601.00,04,,,,,,,,,")); diff --git a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java index 3ee0a5e01..ed7b0534b 100644 --- a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HoopoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HoopoProtocolDecoder(null); + var decoder = inject(new HoopoProtocolDecoder(null)); verifyPosition(decoder, text( "{ \"deviceId\": \"BCCD0654\", \"assetName\": \"BCCD0654\", \"assetType\": \"???? ?????? - ??? 8\", \"eventData\": { \"latitude\": 31.97498, \"longitude\": 34.80802, \"locationName\": \"\", \"accuracyLevel\": \"High\", \"eventType\": \"Arrival\", \"batteryLevel\": 100, \"receiveTime\": \"2021-09-20T18:52:32Z\" }, \"eventTime\": \"2021-09-20T08:52:02Z\", \"serverReportTime\": \"0001-01-01T00:00:00Z\" }")); diff --git a/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java index 228f41ee8..991e0b36d 100644 --- a/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java @@ -10,7 +10,7 @@ public class HuaShengFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuaShengFrameDecoder(); + var decoder = inject(new HuaShengFrameDecoder()); assertEquals( binary("c0010c00120060000000000004000600010100c0"), diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java index 74671b845..7002d7e88 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuaShengProtocolDecoder(null); + var decoder = inject(new HuaShengProtocolDecoder(null)); verifyNull(decoder, binary( "c00000007eaa000000000000cb8000000032313130313030393238323800e9abafffd615d2000000000008000000010015ffffff0000000000000004e7ffffffffff0005000a10080001d5ab000900154b4e4142323531324d4b54353638363630000f00133335343434343131353130333138380014000b00000000000000c0")); diff --git a/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java index d4789032d..6b902fb46 100644 --- a/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java @@ -8,7 +8,7 @@ public class HuabaoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuabaoFrameDecoder(); + var decoder = inject(new HuabaoFrameDecoder()); verifyFrame( binary("283734303139303331313138352c312c3030312c454c4f434b2c332c35323934333929"), diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index c45effbc5..0b36b8f4d 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuabaoProtocolDecoder(null); + var decoder = inject(new HuabaoProtocolDecoder(null)); verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); diff --git a/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java index 81fdae95c..5503ab02c 100644 --- a/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HunterProProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HunterProProtocolDecoder(null); + var decoder = inject(new HunterProProtocolDecoder(null)); verifyPosition(decoder, text( ">0002<$GPRMC,170559.000,A,0328.3045,N,07630.0735,W,0.73,266.16,200816,,,A77, s000078015180\",0MD")); diff --git a/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java index a5141c389..1bd52ce89 100644 --- a/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class IdplProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new IdplProtocolDecoder(null); + var decoder = inject(new IdplProtocolDecoder(null)); verifyPosition(decoder, text( "*ID1,863071011086474,210314,153218,A,1831.4577,N,07351.1433,E,0.79,240.64,9,20,A,1,4.20,0,1,01,1,0,0,A01,R,935D#"), diff --git a/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java index ee3a25cbe..b6e12aef5 100644 --- a/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class IntellitracProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new IntellitracProtocolDecoder(null); + var decoder = inject(new IntellitracProtocolDecoder(null)); verifyPosition(decoder, text( "359316075744331,20201008181424,12.014662,57.826301,0,76,24,10,997,3,0,0.000,4.208,20201008181424,0")); diff --git a/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java index ca72874ef..c668084a1 100644 --- a/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class IotmProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new IotmProtocolDecoder(null); + var decoder = inject(new IotmProtocolDecoder(null)); verifyNull(decoder, MqttMessageBuilders.connect().clientId( "123456789012345").build()); diff --git a/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java index 363185b4c..26f28916c 100644 --- a/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java @@ -8,7 +8,7 @@ public class ItsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ItsFrameDecoder(); + var decoder = inject(new ItsFrameDecoder()); verifyFrame( binary("242c2c3836383732383033373731373434312c312e3444335f4149533134305f312e302c56455253494f4e312e302c32382e3633333731372c4e2c37372e3232323730322c45"), diff --git a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java index dfd86969a..dd8d3a0d9 100644 --- a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class ItsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ItsProtocolDecoder(null); + var decoder = inject(new ItsProtocolDecoder(null)); verifyNull(decoder, text( "$,LGN,MARK,000000000,358980100077446,V0.0.1,AIS140,19.804487,N,75.225876,E,*")); diff --git a/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java index 8a71cb4d5..b08dff4e7 100644 --- a/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Ivt401ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Ivt401ProtocolDecoder(null); + var decoder = inject(new Ivt401ProtocolDecoder(null)); verifyPosition(decoder, text( "(TLA,356917051007891,190118,090211,+16.986606,+82.242416,0,66,4,13,1,5,000,00,0.0,11.59,8.30,37.77,0.0,1,1.02,0,0,208,0,0,0,0,000000000,0,0,0,0,0,0,0,1,8654604,5,9,114)")); diff --git a/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java index 9e01d7d68..b275e6d01 100644 --- a/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class JidoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new JidoProtocolDecoder(null); + var decoder = inject(new JidoProtocolDecoder(null)); verifyPosition(decoder, text( "*12345678910101000,01,A,130517,160435,1820.5845,N,07833.2478,E,20,0,067,045,05,28,26,1,075,Y,1,0000,0000,0000,59")); diff --git a/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java index 13137006c..a1b0acac5 100644 --- a/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class JpKorjarProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new JpKorjarProtocolDecoder(null); + var decoder = inject(new JpKorjarProtocolDecoder(null)); verifyPosition(decoder, text( "KORJAR.PL,329587014519383,160910144240,52.247254N,021.013375E,0.00,1,F:4.18V,1 260 01 794B 3517,")); diff --git a/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java b/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java index 42777e419..1bc5d8480 100644 --- a/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java @@ -8,7 +8,7 @@ public class JsonFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new JsonFrameDecoder(); + var decoder = inject(new JsonFrameDecoder()); verifyFrame( binary("7b226465764964223a2243485a4430384b504430323130343235303436222c2264657654797065223a322c226861726456657273696f6e223a224844545456413139222c226d736754797065223a3131302c2270726f746f636f6c56657273696f6e223a225631222c22736f667456657273696f6e223a22332e312e38222c22737769746368436162537461747573223a2231222c2274786e4e6f223a2231363235323132373431353337227d"), diff --git a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java index eda97ba2d..8e408e50f 100644 --- a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Jt600FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Jt600FrameDecoder(); + var decoder = inject(new Jt600FrameDecoder()); verifyFrame( binary("2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e"), diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 3bf01c1ae..c8db31ad0 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Jt600ProtocolDecoder(null); + var decoder = inject(new Jt600ProtocolDecoder(null)); verifyPosition(decoder, buffer( "(8000632862,P45,290322,132412,25.28217,S,57.54683,W,A,0,0,5,0,0000000000,0,0,9,0)")); diff --git a/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java index 53ef1d5ca..a705d8082 100755 --- a/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class KenjiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new KenjiProtocolDecoder(null); + var decoder = inject(new KenjiProtocolDecoder(null)); verifyPosition(decoder, text( ">C800000,M005004,O0000,I0002,D124057,A,S3137.2783,W05830.2978,T000.0,H254.3,Y240116,G06*17"), diff --git a/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java index 5c2b0732b..155493bea 100644 --- a/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class KhdProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new KhdProtocolDecoder(null); + var decoder = inject(new KhdProtocolDecoder(null)); verifyPosition(decoder, binary( "2929800028258b8c10210731035840031534240542120200000337fb000000ffff5a00000a0000000005005d0d")); diff --git a/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java b/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java index 45c69105b..084ae0498 100644 --- a/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java @@ -8,7 +8,7 @@ public class L100FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new L100FrameDecoder(); + var decoder = inject(new L100FrameDecoder()); verifyFrame( binary("41544c2c4c2c3836383334353033383137313936332c4e2c3230313231382c3039333031362c412c3032352e3036373134342c4e2c3035352e3134343833332c452c3030302e302c4750532c333933392c3432342c30332c30303430352c303038383334"), diff --git a/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java index d4bef3885..56281cda0 100644 --- a/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class L100ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new L100ProtocolDecoder(null); + var decoder = inject(new L100ProtocolDecoder(null)); verifyPosition(decoder, text( "ATL,NP,868004029750174,$GPRMC,062943,A,2533.6719,N,09154.3203,E,0,179,311218,,,*39,#01111011000000,0,0,0,934.82,27.13,4.0,25,405,755,15af,974b,0,0,0,ATL")); diff --git a/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java index c407d1e64..45544241f 100644 --- a/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class LacakProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new LacakProtocolDecoder(null); + var decoder = inject(new LacakProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"location\":{\"event\":\"motionchange\",\"is_moving\":false,\"uuid\":\"0e9a2473-a9a7-4c00-997b-fb97d2154e75\",\"timestamp\":\"2021-07-21T08:06:34.444Z\",\"odometer\":0,\"coords\":{\"latitude\":-6.1148096,\"longitude\":106.6837015,\"accuracy\":3.8,\"speed\":18.67,\"speed_accuracy\":0.26,\"heading\":63,\"heading_accuracy\":0.28,\"altitude\":35.7,\"altitude_accuracy\":3.8},\"activity\":{\"type\":\"still\",\"confidence\":100},\"battery\":{\"is_charging\":false,\"level\":0.79},\"extras\":{}},\"device_id\":\"8737767034\"}"))); diff --git a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java index 1d5819603..aacf9abc8 100644 --- a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class LaipacProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new LaipacProtocolDecoder(null); + var decoder = inject(new LaipacProtocolDecoder(null)); verifyPosition(decoder, text( "$AVRMC,80006405,212645,r,3013.9938,N,08133.3998,W,0.00,0.00,010317,a,4076,0,1,0,0,53170583,310260*78")); diff --git a/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java index aed82eb41..ea31bc99d 100644 --- a/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class LeafSpyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new LeafSpyProtocolDecoder(null); + var decoder = inject(new LeafSpyProtocolDecoder(null)); verifyNull(decoder, request( "/?Lat=60.0&Long=30.0")); diff --git a/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java index ede056f96..674738c82 100644 --- a/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class M2cProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new M2cProtocolDecoder(null); + var decoder = inject(new M2cProtocolDecoder(null)); verifyPositions(decoder, text( "[#M2C,2020,P1.B1.H3.F9.R1,102,864547034433966,1,L,0,20,171221,062016,28.647552,77.192841,0,0,0.0,0,0,64,255,11983,0,0,0,0.0,0,0,0,404,4,1F6,4D77,31,0*7524\r\n", diff --git a/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java index f318dcfef..0d812ebfc 100644 --- a/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class M2mProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new M2mProtocolDecoder(null); + var decoder = inject(new M2mProtocolDecoder(null)); verifyNull(decoder, binary( "235A3C2A2624215C287D70212A21254C7C6421220B0B0B")); diff --git a/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java index 19f9b9da7..be0fe502e 100644 --- a/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MaestroProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MaestroProtocolDecoder(null); + var decoder = inject(new MaestroProtocolDecoder(null)); verifyPosition(decoder, text( "@353893040202807,705,UPV-02,1,13.2,17,0,0,16/09/11,11:42:49,0.352705,32.647918,1210.5,0.000000,35.33,11,0.8,0.000,0!\0")); diff --git a/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java index 74f3ff1ec..a77043b9d 100644 --- a/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ManPowerProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ManPowerProtocolDecoder(null); + var decoder = inject(new ManPowerProtocolDecoder(null)); verifyPosition(decoder, text( "simei:352581250259539,,,tracker,51,24,1.73,130426023608,A,3201.5462,N,03452.2975,E,0.01,28B9,1DED,425,01,1x0x0*0x1*60x+2,en-us,"), diff --git a/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java index ccddb6a11..0c74d4772 100644 --- a/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Mavlink2ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Mavlink2ProtocolDecoder(null); + var decoder = inject(new Mavlink2ProtocolDecoder(null)); verifyAttributes(decoder, binary( "fd1c0000ce01012100004da91f004005d323b89aa30ea6ed070099fb0100f7fffdff0000942c4a88")); diff --git a/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java index 19e5cb0ab..854564cd2 100644 --- a/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java @@ -8,7 +8,7 @@ public class MegastekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MegastekFrameDecoder(); + var decoder = inject(new MegastekFrameDecoder()); verifyFrame( binary("30313337244d47563030322c3335343535303035303239323636392c4756543930302c522c3134313231352c3033313830342c412c2c532c2c452c30302c30332c30302c332e36372c302e3030302c302e30302c3131372e312c302e302c3531302c31302c2c2c2c303030302c303030302c32322c31322c302c202c202c2c312d312c39382c5057204f4e3b21"), diff --git a/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java index 83d62e766..ea55a8b1c 100644 --- a/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MegastekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MegastekProtocolDecoder(null); + var decoder = inject(new MegastekProtocolDecoder(null)); verifyPosition(decoder, text( "$MGV002,860719020193193,,S,070521,160748,V,2255.09165,N,11404.01322,E,00,00,00,,,,,,,,,,,,,,,,,,,10,015,Restart;!")); diff --git a/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java index c0e5f1e97..379cf28f9 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java @@ -11,7 +11,7 @@ public class MeiligaoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeiligaoFrameDecoder(); + var decoder = inject(new MeiligaoFrameDecoder()); assertNull( decoder.decode(null, null, binary("00"))); diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java index 087701be4..4c6eae847 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MeiligaoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeiligaoProtocolDecoder(null); + var decoder = inject(new MeiligaoProtocolDecoder(null)); verifyAttribute(decoder, binary( "2424008f142180340967ff99553033333233302e3030302c412c313531362e383039392c4e2c31303435322e383835352c452c302e30302c33332c3038313232302c2c2a33367c302e387c3132337c323130307c303030302c303030302c303230452c303241417c30323038303030353038394530304531434638347c31437c31373243353832437c3042a8060d0a"), diff --git a/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java index 38d0f2f92..a55935ed2 100644 --- a/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java @@ -10,7 +10,7 @@ public class MeitrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeitrackFrameDecoder(); + var decoder = inject(new MeitrackFrameDecoder()); assertEquals( binary("24244e3132372c3836333037313031333830333036362c4141412c33352c2d312e3330323638302c33362e3835323133352c3135303430393231313032362c412c392c302c302e312c302c352c313635332c343039362c33323634382c3633397c30327c313030347c3930432c303030302c307c307c307c3346467c3330302c2a37430d0a"), diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 1c90468bd..d4ecae10a 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeitrackProtocolDecoder(null); + var decoder = inject(new MeitrackProtocolDecoder(null)); verifyPositions(decoder, binary( "2424423233392c3836323039303035303030373436352c4343452c0100000003004300130006050006000700140015801b00080800000900000a00000b0000165105198d011a630540160005024c5e910103590bfe0204922153290c6b2501000dd5b50200004300130006050006000700140015011b00080800000900000a00000b0000165005198d011a630540010005024c5e910103590bfe0204932153290c6b2501000dd6b50200004300130006050006000700140015011b00080800000900000a00000b0000165205198d011a630540230005024c5e910103590bfe0204942153290c6b2501000dd7b50200002a43330d0a")); diff --git a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java index ca8b67a46..5e36abe5b 100644 --- a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MictrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeStandard() throws Exception { - var decoder = new MictrackProtocolDecoder(null); + var decoder = inject(new MictrackProtocolDecoder(null)); verifyAttributes(decoder, text( "MT;5;867035041396795;Y1;220111085741+test,8c:53:c3:db:e7:26,-58,jiuide-842,80:26:89:f0:5e:4f,-74,jiu2ide 403,94:e4:4b:0a:31:08,-75,jiu3ide,7a:91:e9:50:26:0b,-85,CNet-9rNe,78:91:e9:40:26:0b,-87+0+4092+1")); @@ -48,7 +48,7 @@ public class MictrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeLowAltitude() throws Exception { - var decoder = new MictrackProtocolDecoder(null); + var decoder = inject(new MictrackProtocolDecoder(null)); verifyPositions(decoder, text( "861836051888035$162835.00,A,4139.6460,N,07009.7239,W,,41.53,-25.8,220621")); diff --git a/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java index 69fd82886..275672554 100644 --- a/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MilesmateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MilesmateProtocolDecoder(null); + var decoder = inject(new MilesmateProtocolDecoder(null)); verifyPosition(decoder, text( "ApiString={A:861359037373030,B:09.8,C:00.0,D:083506,E:2838.5529N,F:07717.8049E,G:000.00,H:170918,I:G,J:00004100,K:0000000A,L:1234,M:126.86}")); diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java index 1a9756226..a8f1be855 100644 --- a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MiniFinderProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MiniFinderProtocolDecoder(null); + var decoder = inject(new MiniFinderProtocolDecoder(null)); verifyNull(decoder, text( "!1,867273023933661,V07S.5701.1621,100")); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index 1813a5370..a6006d6a7 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Minifinder2ProtocolDecoder(null); + var decoder = inject(new Minifinder2ProtocolDecoder(null)); verifyPositions(decoder, binary( "AB103D0035A700000110013836373733303035333430333237390924AC5783620103C250162030CC5F0D5002FB432D00AF005A3158006D0A00000B0931EC5783620A000000")); diff --git a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java index ddfa6ad8b..fea74db7a 100644 --- a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MobilogixProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MobilogixProtocolDecoder(null); + var decoder = inject(new MobilogixProtocolDecoder(null)); verifyAttributes(decoder, text( "[2021-08-20 19:27:14,T14,1,V1.3.5,201909000982,53,12.18")); diff --git a/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java index af19b8222..82781550e 100644 --- a/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MoovboxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MoovboxProtocolDecoder(null); + var decoder = inject(new MoovboxProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/", buffer("\n\n3\n\n100.726257\n13.821351\n9.500000\n0.000000\n0.064000\n-27.300000\n0.000000\n9\n\n"))); diff --git a/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java index bd4a97ef4..f3ebb8e5c 100644 --- a/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MotorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MotorProtocolDecoder(null); + var decoder = inject(new MotorProtocolDecoder(null)); verifyPosition(decoder, text( "341200007E7E00007E7E020301803955352401161766210162090501010108191625132655351234567F12345F")); diff --git a/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java index 28b5d3be0..8a5e228c7 100644 --- a/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MtxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MtxProtocolDecoder(null); + var decoder = inject(new MtxProtocolDecoder(null)); verifyPosition(decoder, text( "#MTX,353815011138124,20101226,195550,41.6296399,002.3611174,000,035,000000.00,X,X,1111,000,0,0")); diff --git a/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java index 301b6102b..68a68c9e8 100644 --- a/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MxtProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MxtProtocolDecoder(null); + var decoder = inject(new MxtProtocolDecoder(null)); verifyPosition(decoder, binary( "01a631a7627b00087dc41c40850006aab70affecdf23fd32200080000600000000000000000000001b2ff03b1bb9c4c60214f40100050000006c2d0000f427600051051101de0704")); diff --git a/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java index 60d88999e..8eda687cc 100644 --- a/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NavigilProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavigilProtocolDecoder(null); + var decoder = inject(new NavigilProtocolDecoder(null)); verifyNull(decoder, binary( "01004300040020000000f60203080200e7cd0f510c0000003b00000000000000")); diff --git a/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java index b1282cac7..5c841b211 100644 --- a/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class NavisProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeNtcb() throws Exception { - var decoder = new NavisProtocolDecoder(null); + var decoder = inject(new NavisProtocolDecoder(null)); verifyNull(decoder, binary( "404E5443010000007B000000130044342A3E533A383631373835303035323035303739")); @@ -41,7 +41,7 @@ public class NavisProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeFlex10() throws Exception { - var decoder = new NavisProtocolDecoder(null); + var decoder = inject(new NavisProtocolDecoder(null)); verifyNull(decoder, binary( "404e544301000000c9b5f602130046c52a3e533a383639363936303439373232383235")); @@ -60,7 +60,7 @@ public class NavisProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeFlex20() throws Exception { - var decoder = new NavisProtocolDecoder(null); + var decoder = inject(new NavisProtocolDecoder(null)); verifyNull(decoder, binary( "404e544301000000a9eef602130043fb2a3e533a383639363936303439373337333835")); diff --git a/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java index e73c173b7..d15d01cc0 100644 --- a/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java @@ -8,7 +8,7 @@ public class NavisetFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavisetFrameDecoder(); + var decoder = inject(new NavisetFrameDecoder()); verifyFrame( binary("1310e4073836383230343030353935383436362a060716"), diff --git a/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java index df4e57e8d..d7643b50c 100644 --- a/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NavisetProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavisetProtocolDecoder(null); + var decoder = inject(new NavisetProtocolDecoder(null)); verifyNull(decoder, binary( "1310e4073836383230343030353935383436362a060716")); diff --git a/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java index 562b220d4..360f92447 100644 --- a/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java @@ -9,7 +9,7 @@ public class NavtelecomFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavtelecomFrameDecoder(); + var decoder = inject(new NavtelecomFrameDecoder()); verifyFrame( binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"), @@ -28,7 +28,7 @@ public class NavtelecomFrameDecoderTest extends ProtocolTest { @Test public void testDecodeFull() throws Exception { - var decoder = new NavtelecomFrameDecoder(); + var decoder = inject(new NavtelecomFrameDecoder()); verifyFrame( binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"), diff --git a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java index fd22049fc..301a72b2a 100644 --- a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NavtelecomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavtelecomProtocolDecoder(null); + var decoder = inject(new NavtelecomProtocolDecoder(null)); verifyNull(decoder, binary( "404e5443010000000000000013004e452a3e533a383636373935303331343130363839")); diff --git a/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java index b77bdf658..4e9e55f62 100644 --- a/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NeosProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NeosProtocolDecoder(null); + var decoder = inject(new NeosProtocolDecoder(null)); verifyPosition(decoder, text( ">12345678,1,1,070201,144111,W05829.2613,S3435.2313,,00,034,25,00,126-000,0,3,11111111*2d!\r\n")); diff --git a/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java index 9ab4aea4f..239d892f8 100644 --- a/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NetProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NetProtocolDecoder(null); + var decoder = inject(new NetProtocolDecoder(null)); verifyPosition(decoder, text( "@L03686090604017761712271020161807037078881037233751000000010F850036980A4000")); diff --git a/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java index 7707094a5..03aaa49aa 100644 --- a/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NiotProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NiotProtocolDecoder(null); + var decoder = inject(new NiotProtocolDecoder(null)); verifyPosition(decoder, binary( "585880004c08675430347318522007161451458024b28003f566ee00000328f8000748217ffc500729007a280000000000160001383932353430323130363431363738373136323100050002004e00570d"), diff --git a/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java index a30847160..3f1ec7aee 100644 --- a/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NoranProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NoranProtocolDecoder(null); + var decoder = inject(new NoranProtocolDecoder(null)); verifyNull(decoder, binary( "0d0a2a4b57000d000080010d0a")); diff --git a/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java index 76c7cafb9..dd5e1d9b9 100644 --- a/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java @@ -10,7 +10,7 @@ public class NvsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NvsFrameDecoder(); + var decoder = inject(new NvsFrameDecoder()); assertEquals( binary("0012333537303430303630303137383234312e38"), diff --git a/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java index ed4008d47..61d050679 100644 --- a/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NvsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NvsProtocolDecoder(null); + var decoder = inject(new NvsProtocolDecoder(null)); verifyNull(decoder, binary( "0012333537303430303630303137383234312e38")); diff --git a/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java index 81de06f89..b3bd9aca7 100644 --- a/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NyitechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NyitechProtocolDecoder(null); + var decoder = inject(new NyitechProtocolDecoder(null)); verifyPosition(decoder, binary( "4040690030313436383230303238373201201c0c12031a308080801c0c12031a3007d67e7e08aceb841002000000ae08000000000000000000000000001e002900f0ffdd002700f2ffe0002700f2ffe1002400f0ffdf002400f3ffe3008a00ffff01010000a9c70d0a")); diff --git a/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java index 08ebf9995..8272fe41e 100644 --- a/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ObdDongleProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ObdDongleProtocolDecoder(null); + var decoder = inject(new ObdDongleProtocolDecoder(null)); verifyNull(decoder, binary( "55550003383634383637303232353131303135010009010011023402010201ABAAAA")); diff --git a/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java index 023158f21..6015f1d18 100644 --- a/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OigoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OigoProtocolDecoder(null); + var decoder = inject(new OigoProtocolDecoder(null)); verifyPosition(decoder, binary( "7e002e000000146310002523830400001bfb000369150f310c0591594d062ac0c0141508011303cd63101604fd00000000")); diff --git a/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java index 0df537642..19c96ed9a 100644 --- a/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OkoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OkoProtocolDecoder(null); + var decoder = inject(new OkoProtocolDecoder(null)); verifyPosition(decoder, text( "{861001001012919,090745,A,4944.302,N,02353.366,E,0.0,225,251120,7,0.27,F9,11.3,1}")); diff --git a/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java b/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java index c8bbf399a..8e8d9b1cf 100644 --- a/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java @@ -8,7 +8,7 @@ public class OmnicommFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OmnicommFrameDecoder(); + var decoder = inject(new OmnicommFrameDecoder()); verifyFrame( binary("c08600004566"), diff --git a/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java index 76b476fc2..5b3b08194 100644 --- a/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OmnicommProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OmnicommProtocolDecoder(null); + var decoder = inject(new OmnicommProtocolDecoder(null)); verifyNull(decoder, binary( "c080080061a61915340100001dec")); diff --git a/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java index 9fbd79cbf..5494301d8 100644 --- a/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OpenGtsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OpenGtsProtocolDecoder(null); + var decoder = inject(new OpenGtsProtocolDecoder(null)); verifyPosition(decoder, request( "/?id=999000000000003&gprmc=$GPRMC,082202.0,A,5006.747329,N,01416.512315,E,0.0,,131018,1.2,E,A*2E")); diff --git a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java index 7d3068c02..408053496 100644 --- a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OrbcommProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OrbcommProtocolDecoder(null); + var decoder = inject(new OrbcommProtocolDecoder(null)); verifyNull(decoder, response( buffer("{\"ErrorID\":0,\"NextStartUTC\":\"\",\"Messages\":null}"))); diff --git a/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java index 7368a9d4e..f5b98574c 100644 --- a/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OrionProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OrionProtocolDecoder(null); + var decoder = inject(new OrionProtocolDecoder(null)); verifyPositions(decoder, binary( "5057000137bf6236235a0331b5c6e402a3b5ecff5102980003000e0c1d172936080e0c1d172936b03b01000882050000008e080000000000008c0300940500000084030085030003067600900113150000000000000000000000000000000000000004a4c8")); diff --git a/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java index a87b45ec4..3b8a94613 100644 --- a/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OsmAndProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OsmAndProtocolDecoder(null); + var decoder = inject(new OsmAndProtocolDecoder(null)); verifyNotNull(decoder, request( "/?id=123456×tamp=1377177267&cell=257,02,16,2224&cell=257,02,16,2223,-90&wifi=00-14-22-01-23-45,-80&wifi=00-1C-B3-09-85-15,-70")); diff --git a/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java index 1194f7970..edb7d1aad 100644 --- a/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class OutsafeProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OutsafeProtocolDecoder(null); + var decoder = inject(new OutsafeProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"device\":\"865303040103725\",\"owner\":\"\",\"data\":{\"cmd\":\"\",\"ms1\":-1,\"ms2\":-1,\"ms3\":0,\"ms4\":0,\"observation\":\"\",\"content\":null},\"time\":1589277568,\"origin\":\"mqgatte\",\"latitude\":19.346855,\"longitude\":-99.29587,\"altitude\":2757,\"heading\":0,\"rssi\":0}"))); diff --git a/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java index 55b48fb05..03332e7fe 100644 --- a/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class OwnTracksProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OwnTracksProtocolDecoder(null); + var decoder = inject(new OwnTracksProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"_type\":\"location\",\"acc\":15,\"alt\":440,\"batt\":46,\"conn\":\"w\",\"lat\":46.0681247,\"lon\":11.1512805,\"t\":\"u\",\"tid\":\"5t\",\"tst\":1551874878,\"vac\":2,\"vel\":0}"))); diff --git a/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java index edf508314..bde464162 100644 --- a/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java @@ -22,7 +22,7 @@ public class PacificTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PacificTrackProtocolDecoder(null); + var decoder = inject(new PacificTrackProtocolDecoder(null)); verifyAttributes(decoder, binary( "FB80019702808835275309000091108181B2C08F0143000E10000000010000001400010192DF0143288063810A8202835584D285B486E68780882D89C38A788BCE8C3A8D3C8E418F809073A008ACA16600A225A0C0000F4240C10003DF2CC200004E20C3004428C0C4000008C6C5000316A4E011314334424A57464758444C35333137373302A086AB569DFE110E02A8811203FF81000190820100")); diff --git a/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java index e4c9bf449..97020343f 100644 --- a/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PathAwayProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PathAwayProtocolDecoder(null); + var decoder = inject(new PathAwayProtocolDecoder(null)); verifyPosition(decoder, request( "?UserName=name&Password=pass&LOC=$PWS,1,\"Roger\",,,100107,122846,45.317270,-79.642219,45.00,42,1,\"Comment\",0*58")); diff --git a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java index b39060420..475ac0125 100644 --- a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class PiligrimProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PiligrimProtocolDecoder(null); + var decoder = inject(new PiligrimProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/bingps?imei=868204005544720&csq=18&vout=00&vin=4050&dataid=00000000", diff --git a/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java index 2d134d967..8b15d70a6 100644 --- a/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class PluginProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PluginProtocolDecoder(null); + var decoder = inject(new PluginProtocolDecoder(null)); verifyPosition(decoder, text( "$$STATUS,000000900005,20210521111252,27.171105,-25.600934,62.0,323,0,-1,2,0.000,2147489155,0.00,0,0,0.0,0.0,0,0,0,0,0,0,0,0,0")); diff --git a/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java index 592267b9e..8bf109d11 100644 --- a/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class PolteProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PolteProtocolDecoder(null); + var decoder = inject(new PolteProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"_id\":\"5f75cf7b02c5023bfc0beaf7\",\"location\":{\"LocationMetrics\":{\"EnvironmentDensity\":1,\"LocationType\":2,\"carrierInfo\":{\"aux\":{\"PLMN\":\"310410\",\"country\":\"United States\",\"name\":\"ATT Wireless Inc\"},\"crs\":{\"PLMN\":\"310410\",\"country\":\"United States\",\"name\":\"ATT Wireless Inc\"}},\"hdop\":1850000,\"leversion\":\"2.2.18-20200729T140651\",\"towercount\":1},\"altitude\":0.0011297669261693954,\"confidence\":783.7972188868215,\"detected_at\":1601556342,\"latitude\":29.77368956725161,\"longitude\":-98.26530342694024,\"towerDB\":\"default\",\"ueToken\":\"ALT12503DE04336CB2E3A4A113FCDE05DF05A6F\",\"uid\":\"WZuDMv5Je\"},\"report\":{\"battery\":{\"count\":555,\"level\":100,\"voltage\":3.52},\"event\":3,\"time\":\"2020-10-01T12:45:48.207Z\"},\"time\":\"2020-10-01T12:45:42Z\",\"ueToken\":\"ALT12503DE04336CB2E3A4A113FCDE05DF05A6F\",\"uid\":\"WZuDMv5Je\"}"))); diff --git a/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java index 37798d960..8bc16d373 100644 --- a/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PortmanProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PortmanProtocolDecoder(null); + var decoder = inject(new PortmanProtocolDecoder(null)); verifyPosition(decoder, text( "$EXT,P0RTMANGRANT,A,210609201710,N0951.6879W08357.0129,0,0,NA,NA,11,25,174700.25,NA,01820000,108")); diff --git a/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java index 8a4f257f5..5dbde7846 100644 --- a/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PretraceProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PretraceProtocolDecoder(null); + var decoder = inject(new PretraceProtocolDecoder(null)); verifyPosition(decoder, text( "(867967021915915U1110A1701201500102238.1700N11401.9324E000264000000000009001790000000,&P11A4,F1050^47")); diff --git a/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java index a9373e22e..8c2081641 100644 --- a/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PricolProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PricolProtocolDecoder(null); + var decoder = inject(new PricolProtocolDecoder(null)); verifyPosition(decoder, binary( "3c5052493030303350020000011402110b222b0455152e4e001de819ca450000000000000003820249000000000000000000000000000000000000000040003e")); diff --git a/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java index 6e59f2876..9129a3079 100644 --- a/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ProgressProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ProgressProtocolDecoder(null); + var decoder = inject(new ProgressProtocolDecoder(null)); verifyNull(decoder, binary( "020037000100000003003131310f003335343836383035313339303036320f00323530303136333832383531353535010000000100000000000000e6bb97b6")); diff --git a/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java b/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java index 96993b97b..172d85df6 100644 --- a/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java @@ -8,7 +8,7 @@ public class PstFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PstFrameDecoder(); + var decoder = inject(new PstFrameDecoder()); verifyFrame( binary("2fafac5a050f0000e0022fafac5a01891e882bbfdd06dd577c9865620a0efe524c419f940b6710f5ba0c86e5868ffc97c77eaaf166a31dba63f9894e98a91b9486c94e79ce537359737a5e9385431a590eb20b5115a2b7939e4e66ae"), diff --git a/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java index 445c333c1..880caf727 100644 --- a/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PstProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PstProtocolDecoder(null); + var decoder = inject(new PstProtocolDecoder(null)); verifyPosition(decoder, binary( "2faf97de06000024db0551380cbb08070b040000015a0c09b50177e5100a1822da0d010d0f0451380628101451380cc384b800488a84036901b202d3010001061103ffff00150203523687")); diff --git a/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java index 24cfd316a..a5f5d7e77 100644 --- a/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Pt215ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt215ProtocolDecoder(null); + var decoder = inject(new Pt215ProtocolDecoder(null)); verifyNull(decoder, binary( "58580d010359339075435451010d0a")); diff --git a/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java index 44f57601c..f7b278139 100644 --- a/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Pt3000ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt3000ProtocolDecoder(null); + var decoder = inject(new Pt3000ProtocolDecoder(null)); verifyPosition(decoder, text( "%356939010012099,$GPRMC,124945.752,A,4436.6245,N,01054.4634,E,0.11,358.52,060408,,,A,+393334347445,N028d"), diff --git a/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java index 2559ad145..854c789b8 100644 --- a/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Pt502FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt502FrameDecoder(); + var decoder = inject(new Pt502FrameDecoder()); verifyFrame( binary("24504844302c3936302cffd8ffdb008400140e0f120f0d14121012171514181e32211e1c1c1e3d2c2e243249404c4b47404645505a736250556d5645466488656d777b8182814e608d978c7d96737e817c011517171e1a1e3b21213b7c5346537c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffc000110800f0014003012100021101031101ffdd0004000affc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00e5292800ef450020a2800a2801d49400b450014b40052e2800a69340094a05007fffd0e5d14b10055b51b00c76a00527273494005250014500251400525001450015347c25003a928010d25007ffd1e52909a00290d0014b40052d0014500145002e297b50018a280109a6d002d2e2803fffd2e7a04da3777a94fbd0025140052500145002514005250014940054e381400b494008690d007fffd3e4f345001486800a5a005a2800a2801680280168a002909e280100cd028016a48937bfb5007fffd4c5038a42280128a004a280128a003ad2500251400945002a8cb0a9a80133450026692803ffd5e4e8a004a2801694500145002d18a005c5140052e280109a69a0029680140abb147b139eb401ffd6c62290d00251400949400114940052500252d002525003e31c93525002521a004a4a00ffd7e4a8a00281400a29d40094b40053ba500252d0018a31400d3cd250018cd2d005ab58777ccdd074ab645007ffd0c72290d00348a2801280"), diff --git a/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java index a68471c95..f310b2227 100644 --- a/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Pt502ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt502ProtocolDecoder(null); + var decoder = inject(new Pt502ProtocolDecoder(null)); verifyNull(decoder, binary( "24504844302c3936302cffd8ffdb008400140e0f120f0d14121012171514181e32211e1c1c1e3d2c2e243249404c4b47404645505a736250556d5645466488656d777b8182814e608d978c7d96737e817c011517171e1a1e3b21213b7c5346537c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffc000110800f0014003012100021101031101ffdd0004000affc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00e5292800ef450020a2800a2801d49400b450014b40052e2800a69340094a05007fffd0e5d14b10055b51b00c76a00527273494005250014500251400525001450015347c25003a928010d25007ffd1e52909a00290d0014b40052d0014500145002e297b50018a280109a6d002d2e2803fffd2e7a04da3777a94fbd0025140052500145002514005250014940054e381400b494008690d007fffd3e4f345001486800a5a005a2800a2801680280168a002909e280100cd028016a48937bfb5007fffd4c5038a42280128a004a280128a003ad2500251400945002a8cb0a9a80133450026692803ffd5e4e8a004a2801694500145002d18a005c5140052e280109a69a0029680140abb147b139eb401ffd6c62290d00251400949400114940052500252d002525003e31c93525002521a004a4a00ffd7e4a8a00281400a29d40094b40053ba500252d0018a31400d3cd250018cd2d005ab58777ccdd074ab645007ffd0c72290d00348a2801280")); diff --git a/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java index ad987240c..b198ac28e 100644 --- a/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Pt60ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt60ProtocolDecoder(null); + var decoder = inject(new Pt60ProtocolDecoder(null)); verifyNull(decoder, text( "@B#@|01|006|864891030184954|9425010450971470|20181213093127|2|1|")); diff --git a/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java index acb7277b5..a363022f0 100644 --- a/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class R12wProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new R12wProtocolDecoder(null); + var decoder = inject(new R12wProtocolDecoder(null)); verifyNull(decoder, text( "$HX,0001,860721009104316,e92c,933402042499509,55792760080,12345678,01,a8d940a9,#,50,")); diff --git a/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java index 22902079a..ff40c19a3 100644 --- a/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RaceDynamicsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RaceDynamicsProtocolDecoder(null); + var decoder = inject(new RaceDynamicsProtocolDecoder(null)); verifyNull(decoder, text( "$GPRMC,12,260819,100708,862549040661129,")); diff --git a/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java index be1e4de0b..b5a2555b1 100644 --- a/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RadarProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RadarProtocolDecoder(null); + var decoder = inject(new RadarProtocolDecoder(null)); verifyPositions(decoder, binary( "361800011459015cb497554c01c101ff003500050038000207ff831c04c01f1c00555cb464895cb46487ff7f04eafeffdbd80000079402ead0000000110000000000120d2aff150000000000000002000a00050002436c61726f0000000000008b00000003764500037653005207ff831c04c01f1c00555cb4648a5cb46489ff7f04eafeffdbd80000079402ead0000000010000000000120e00ff150000000000000002000800060002436c61726f0000000000008d00000003764600037654000207ff831c04c01f1c00555cb464d85cb464d7ff7f04eafeffdbd80000079402ead0000000110000000000120e2aff150000000000000002000700070003436c61726f0000000000008d000000037694000376a2005207ff831c04c01f1c00555cb464d95cb464d9ff7f04eafeffdbd80000079402eac0000000010000000000120e00ff150000000000000002000700070003436c61726f0000000000008d000000037695000376a3000207ff831c04c01f1c00555cb465065cb46504ff7f04eafeffdbd80000079402ead0000000110000000000120e2aff150000000000000000000500060005436c61726f0000000000008d0000000376c2000376d07ed7")); diff --git a/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java index 1b111ee5d..3da671dbf 100644 --- a/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RaveonProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RaveonProtocolDecoder(null); + var decoder = inject(new RaveonProtocolDecoder(null)); verifyPosition(decoder, text( "$PRAVE,0001,0001,3308.9051,-11713.1164,195348,1,10,168,31,13.3,3,-83,0,0,,1003.4*66")); diff --git a/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java index 803cfb48a..5bdfd6816 100644 --- a/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RecodaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RecodaProtocolDecoder(null); + var decoder = inject(new RecodaProtocolDecoder(null)); verifyNull(decoder, binary( "01100020480000000300000030393535360000000000000001000000303030303000000000000000000000000000000000000000006100004531313037353500ffffffffffff0000")); diff --git a/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java index 4af77cfbf..eb591a5f6 100644 --- a/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RetranslatorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RetranslatorProtocolDecoder(null); + var decoder = inject(new RetranslatorProtocolDecoder(null)); verifyPosition(decoder, binary( "74000000333533393736303133343435343835004B0BFB70000000030BBB000000270102706F73696E666F00A027AFDF5D9848403AC7253383DD4B400000000000805A40003601460B0BBB0000001200047077725F657874002B8716D9CE973B400BBB00000011010361766C5F696E707574730000000001")); diff --git a/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java index e0890a5fc..0d7eeb0df 100644 --- a/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RitiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RitiProtocolDecoder(null); + var decoder = inject(new RitiProtocolDecoder(null)); verifyPosition(decoder, binary( "3b28a2a2056315316d4000008100000000000000005f710000244750524d432c3138303535332e3030302c412c353532342e383437312c4e2c30313133342e313837382c452c302e30302c2c3032313231332c2c2c412a37340d0a00000000000000000000000000000000040404")); diff --git a/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java index eaf83458d..e4b30538c 100644 --- a/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java @@ -8,7 +8,7 @@ public class RoboTrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RoboTrackFrameDecoder(); + var decoder = inject(new RoboTrackFrameDecoder()); verifyFrame( binary("00524f424f545241434b00000000000000383638323034303032323533343136313233343536373839303132312e313261000000312e353761000000312e3030000000003e"), diff --git a/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java index 40218efdb..db1617c9e 100644 --- a/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RoboTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RoboTrackProtocolDecoder(null); + var decoder = inject(new RoboTrackProtocolDecoder(null)); verifyNull(decoder, binary( "00524f424f545241434b00000000000000383638323034303032323533343136313233343536373839303132312e313261000000312e353761000000312e3030000000003e")); diff --git a/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java index 71313e449..b301507fb 100644 --- a/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class RstProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RstProtocolDecoder(null); + var decoder = inject(new RstProtocolDecoder(null)); verifyNull(decoder, text( "RST;A;RST-MINIv2;V7.04;008051261;124;29;04-04-2021 17:27:26;04-04-2021 17:27:26;-1.280811;-47.931755;7353;79;1;14;7315;26;10;0;1855;0;0;0;0;5;5;-1.280821;-47.931747;04-04-2021 17:52:23;6;-1.280863;-47.931770;04-04-2021 18:12:19;5;-1.280844;-47.931763;04-04-2021 17:28:02;5;-1.280900;-47.931770;04-04-2021 19:04:27;4;-1.280843;-47.931747;04-04-2021 18:21:45;04-04-2021 19:29:59;04-04-2021 19:29:59;-1.280770;-47.931595;1;15;0;0;0;0;FIM;")); diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java index eca7518a7..89d4a02cc 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RuptelaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RuptelaProtocolDecoder(null); + var decoder = inject(new RuptelaProtocolDecoder(null)); verifyNull(decoder, binary( "002e000316d53d58d6020f4573303430302e30332e36382e30340000c2b3090d0e950000827b000003e80000003c003c1681")); diff --git a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java index ec795c9eb..2b7f40c82 100644 --- a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class S168ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new S168ProtocolDecoder(null); + var decoder = inject(new S168ProtocolDecoder(null)); verifyAttributes(decoder, text( "S168#861118010104168#00ec#0016#SYNC:0093;STATUS:91,51")); diff --git a/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java index ced40acd0..15b1d0451 100644 --- a/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java @@ -10,7 +10,7 @@ public class SabertekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SabertekFrameDecoder(); + var decoder = inject(new SabertekFrameDecoder()); assertEquals( binary("2c3939393939393939392c332c34302c36352c372c302c312c2d32352e3738313636362c32382e3235343730322c34302c3236382c313431342c382c35353632332c"), diff --git a/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java index 148695dcd..6aafa325f 100644 --- a/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SabertekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SabertekProtocolDecoder(null); + var decoder = inject(new SabertekProtocolDecoder(null)); verifyPosition(decoder, text( ",999999999,3,40,65,7,0,1,-25.781666,28.254702,40,268,1414,8,55623,")); diff --git a/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java index 223f4f12f..d0ae6fabf 100644 --- a/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SanavProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SanavProtocolDecoder(null); + var decoder = inject(new SanavProtocolDecoder(null)); verifyPosition(decoder, text( "imei=353197040023431&rmc=$GPRMC,015258.000,A,2457.8101,N,12125.5393,E,0.00,0.00,210111,,*18,AUTO,0300,2.1,10,466,97,34E7,3391,74,466,9 7,3F2D,3391,65,466,97,39C9,3391,79,466,97,3F2C,3391,81,466,97,0000,00 00,83,466,97,0000,0000,85,466,97,0000,0000,85,1,24")); diff --git a/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java index 23bd6d80b..57398dd84 100644 --- a/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SanulProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SanulProtocolDecoder(null); + var decoder = inject(new SanulProtocolDecoder(null)); verifyNull(decoder, binary( "aa007020000100000000000033353333353830313831353431313700000000000000000000")); diff --git a/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java index dcd51063c..0fe16377d 100644 --- a/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SatsolProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SatsolProtocolDecoder(null); + var decoder = inject(new SatsolProtocolDecoder(null)); verifyPositions(decoder, binary( "f0e1bf4cb2ec1600e1005f8791e901000000c959515c2cc24a03aeadcd010e01a800250001090201878e92e901000000cb59515c2dc24a03b8adcd018801a8001d0001080201325993e901000000cc59515c2fc24a03bfadcd01ab01a800220001080201dd8194e901000000cd59515c32c24a03ceadcd015801a8002500010802015f3795e905000900ce59515c32c24a03d8adcd01f600a700250001091401000000000000000000863496e901000000cf59515c34c24a03ddadcd019b00a700280001090201714197e904000600cf59515c34c24a03ddadcd019b00a7002800010a1401becd07001901")); diff --git a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java index 7e2812714..66d5f5e69 100644 --- a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class SigfoxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SigfoxProtocolDecoder(null); + var decoder = inject(new SigfoxProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{ \"device\":\"BFE47E\", \"time\":1590497040, \"data\":\"10297eb01e621122070000be\", \"seqNumber\":8, \"deviceTypeId\":\"5ecb8bfac563d620cc9e6798\", \"ack\":false }"))); diff --git a/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java index d264895fc..0d7eb4f16 100644 --- a/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SiwiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SiwiProtocolDecoder(null); + var decoder = inject(new SiwiProtocolDecoder(null)); verifyPosition(decoder, text( "$SIWI,868957040831465,44,E,,,1,1,1,16.79,0,0,5,A,17.204447,78.355087,534,44,140955,180221,11,1,15,5,4322,0,0,0,0,0,0,1.0,1.6CPTASF_6.60,0!")); diff --git a/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java index a248056f8..e59e3c3f0 100644 --- a/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SkypatrolProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SkypatrolProtocolDecoder(null); + var decoder = inject(new SkypatrolProtocolDecoder(null)); verifyNull(decoder, binary( "000a02171101303131373232303031333537393833060200000006202020202020202020312020202020202030313137323230303133353739383320")); diff --git a/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java index 740d1b62c..258eb0fce 100644 --- a/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SmartSoleProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SmartSoleProtocolDecoder(null); + var decoder = inject(new SmartSoleProtocolDecoder(null)); verifyPosition(decoder, text( "#GTXRP=359366080000385,8,180514200051,34.041981,-118.255806,60,1,1,7,1.80,180514200051,4.16,11")); diff --git a/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java index d806fd790..de025c18e 100644 --- a/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SmokeyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SmokeyProtocolDecoder(null); + var decoder = inject(new SmokeyProtocolDecoder(null)); verifyAttributes(decoder, binary( "534d0300865101019383025f0403000000000b86250200000c0000028f000102f8cc0900127f08")); diff --git a/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java index 7202aaefb..445628f6d 100644 --- a/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class SolarPoweredProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SolarPoweredProtocolDecoder(null); + var decoder = inject(new SolarPoweredProtocolDecoder(null)); verifyAttribute(decoder, binary( "7e850256553309440011003e81131914030600332301a61ed709209ff40014b89082020f0283100000f908000000440000003d1f19021784114161726f6e34475630312d323030333031057e"), diff --git a/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java index 7f8e2b58f..03d0e97f0 100644 --- a/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class SpotProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SpotProtocolDecoder(null); + var decoder = inject(new SpotProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/", buffer( "\n", diff --git a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java index 1710ccbb9..0a6ad0163 100644 --- a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class StarLinkProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StarLinkProtocolDecoder(null); + var decoder = inject(new StarLinkProtocolDecoder(null)); decoder.setFormat("#IMEI#,#EDT#,#PDT#,#LAT#,#LONG#,#SPD#,#IGN#,#ODO#,#DUR#,#TDUR#,#LAC#,#CID#,#VIN#,#VBAT#,#EID#,#EDSC#,#DRV#,#SATU#,#CSS#,#OUT1#,#OUT2#,#CFL#"); diff --git a/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java index 851d4eac6..84c470970 100644 --- a/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class StarcomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StarcomProtocolDecoder(null); + var decoder = inject(new StarcomProtocolDecoder(null)); verifyPosition(decoder, text( "|unit=416307,unittype=5,address=186.167.243.28,kind=14,software_version=14.02.18,hardware_type=17,gps_type=6,longitude=-67.85891,latitude=10.21988,datetime_actual=2019/05/07 21:59:38,network=TCPIP.1|\r\n")); diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index cea079156..e8eecae96 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class StartekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StartekProtocolDecoder(null); + var decoder = inject(new StartekProtocolDecoder(null)); verifyAttribute(decoder, text( "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52"), diff --git a/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java index 74b30f9eb..c618ac21c 100644 --- a/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class StbProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StbProtocolDecoder(null); + var decoder = inject(new StbProtocolDecoder(null)); verifyAttributes(decoder, text( "{\"attrList\":[{\"id\":\"02101001\",\"value\":\"510101051161205774\"},{\"id\":\"02105001\",\"value\":\"-61\"},{\"id\":\"02102001\",\"value\":\"1\"},{\"doorId\":\"1\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"1\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"2\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"2\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"3\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"3\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"4\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"4\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"4\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"4\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"5\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"5\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"5\",\"id\":\"02103001\",\"value\":\"1\"},{\"doorId\":\"5\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"6\",\"id\":\"02104001\",\"value\":\"2\"},{\"doorId\":\"6\",\"id\":\"02106001\",\"value\":\"BT106002320JPZZ210718002\"},{\"doorId\":\"6\",\"id\":\"02109001\",\"value\":\"98\"},{\"doorId\":\"6\",\"id\":\"02110001\",\"value\":\"100\"},{\"doorId\":\"6\",\"id\":\"01118001\",\"value\":\"27\"},{\"doorId\":\"6\",\"id\":\"01119001\",\"value\":\"26\"},{\"doorId\":\"6\",\"id\":\"01120001\",\"value\":\"28\"},{\"doorId\":\"6\",\"id\":\"02114001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02116001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02117001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"01121001\",\"value\":\"2\"},{\"doorId\":\"6\",\"id\":\"02130001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"01122001\",\"value\":\"4\"},{\"doorId\":\"6\",\"id\":\"02001001\",\"value\":\"000\"},{\"doorId\":\"6\",\"id\":\"02002001\",\"value\":\"000\"},{\"doorId\":\"6\",\"id\":\"01116001\",\"value\":\"20\"},{\"doorId\":\"6\",\"id\":\"01117001\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117002\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117003\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117004\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117005\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117006\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117007\",\"value\":\"3325\"},{\"doorId\":\"6\",\"id\":\"01117008\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117009\",\"value\":\"3325\"},{\"doorId\":\"6\",\"id\":\"01117010\",\"value\":\"3326\"},{\"doorId\":\"6\",\"id\":\"01117011\",\"value\":\"3326\"},{\"doorId\":\"6\",\"id\":\"01117012\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117013\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117014\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117015\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117016\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117017\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117018\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117019\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117020\",\"value\":\"3323\"},{\"batteryId\":\"BT106002320JPZZ210718002\",\"doorId\":\"6\",\"id\":\"02103001\",\"value\":\"1\"},{\"batteryId\":\"BT106002320JPZZ210718002\",\"doorId\":\"6\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"7\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"7\",\"id\":\"02103001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"8\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"8\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"8\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"8\",\"id\":\"02118001\",\"value\":\"1\"},{\"id\":\"02111001\",\"value\":\"0.0\"},{\"id\":\"02112001\",\"value\":\"0.0\"},{\"id\":\"02107001\",\"value\":\"229.1\"},{\"id\":\"02108001\",\"value\":\"1.005\"},{\"id\":\"02120001\",\"value\":\"143.76\"},{\"id\":\"02113001\",\"value\":\"29\"},{\"id\":\"02119001\",\"value\":\"1\"}],\"devId\":\"CHZD08KPD0210425046\",\"isFull\":1,\"msgType\":310,\"txnNo\":\"1636707944778\"}")); diff --git a/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java index e13f74604..3ef4b1901 100644 --- a/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Stl060ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Stl060ProtocolDecoder(null); + var decoder = inject(new Stl060ProtocolDecoder(null)); verifyPosition(decoder, text( "$1,357804048043099,D001,AP29AW0963,23/02/14,14:06:54,17248488N,078342226E,0.08,193.12,1,1,1,1,1,A"), diff --git a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java index 99cbeac2f..96fed314c 100644 --- a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java @@ -8,7 +8,7 @@ public class SuntechFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SuntechFrameDecoder(); + var decoder = inject(new SuntechFrameDecoder()); verifyFrame( binary("81004e05200013383fffff3401000301130a0512080400000000000000000000000047f9d5846a06810072225214010100020300a8002604c1000004b000000470000025a100000000000025c4000000a6"), diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 098758728..7fed55454 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeTemperature() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); decoder.setHbm(true); decoder.setIncludeAdc(true); @@ -39,7 +39,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeRpm() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); decoder.setHbm(true); decoder.setIncludeRpm(true); @@ -53,7 +53,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeHours() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); decoder.setHbm(true); @@ -66,7 +66,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeDriver() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); verifyAttribute(decoder, buffer( "ST300HTE;511050566;45;308;20200909;13:38:38;0;12.50;001354;0.0;1;0;1;1;0;-27.636632;-052.277933;-27.636675;-052.277947;000.000;002.296;0;00000000000000"), @@ -81,7 +81,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); verifyPosition(decoder, buffer( "BLE;1140000053;114;1.0.1;20211001;17:27:09;+28.433465;-82.565891;1;-43;-46;-41;ACB89523EF68;247;0;0")); @@ -262,7 +262,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeCrash() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); verifyAttribute(decoder, binary( "4352523b303931303030303036333b313b313b303135303b16011c150f0ad82f6c0000000000ae037085fbff7700fd00faff6300f30000006800fb000d007100fa00f32f6c00000000005e044a80fcff6f000301e1ff5d00e900e1ff6400e600f4ff5b00ec000a306c00000000002104248306006c000501fcff5b00e00001006e000101eeff4e00e10022306c00000000005c041a7e00006a00010100005d00f800b5ff7cffdf0050009300fc003b44350d"), diff --git a/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java index 29ec670aa..e96c9b62d 100755 --- a/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SupermateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SupermateProtocolDecoder(null); + var decoder = inject(new SupermateProtocolDecoder(null)); verifyPosition(decoder, text( "2:359672050130411:1:*,00000000,XT,A,10031b,140b28,80ad4c72,81ba2d2c,06ab,238c,020204010000,12,0,0000,0003e6")); diff --git a/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java index 8a3a74753..fb9053706 100644 --- a/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SviasProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SviasProtocolDecoder(null); + var decoder = inject(new SviasProtocolDecoder(null)); verifyPosition(decoder, text( "[7061,3041,57,20324277,710,40618,141342,-93155840,-371754060,0,20469,0,16,1,0,0,11323,100,9,,32,4695")); diff --git a/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java index 10b033985..923b7abfb 100644 --- a/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SwiftechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SwiftechProtocolDecoder(null); + var decoder = inject(new SwiftechProtocolDecoder(null)); verifyPosition(decoder, text( "@@861551041946971,,0,102040,1023.9670,N,07606.8160,E,2.26,151220,A,0127,1,1,03962,00000,#")); diff --git a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java index ba981598d..6ce47db94 100644 --- a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class T55ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T55ProtocolDecoder(null); + var decoder = inject(new T55ProtocolDecoder(null)); verifyPosition(decoder, text( "QZE,868994033976700,35,28062020,113553,22.13673,114.57263,0,22,A,0")); @@ -121,7 +121,7 @@ public class T55ProtocolDecoderTest extends ProtocolTest { // Maxon devices can send NMEA before identification - var decoder = new T55ProtocolDecoder(null); + var decoder = inject(new T55ProtocolDecoder(null)); verifyNull(decoder, text( "$GPRMC,012006,A,4828.10,N,1353.52,E,0.00,0.00,180915,020.3,E*42")); diff --git a/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java b/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java index dd5929b04..40d5bc9e9 100644 --- a/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java @@ -8,7 +8,7 @@ public class T57FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T57FrameDecoder(); + var decoder = inject(new T57FrameDecoder()); verifyFrame( binary("2a5435372346312354353731313137303031233330313131372330303038343323323233342e31333033234e2330383832362e313731342345232b302e3234322c2b302e3130392c2d302e37383923302e30303023362e323030303023413223342e3223"), diff --git a/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java index 376aab1da..2e097562b 100644 --- a/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class T57ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T57ProtocolDecoder(null); + var decoder = inject(new T57ProtocolDecoder(null)); verifyPosition(decoder, text( "*T57#F1#T571117001#301117#000843#2234.1303#N#08826.1714#E#+0.242,+0.109,-0.789#0.000#6.20000#A2#4.2#")); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java index 1dd4e8619..b5917e3cc 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class T800xProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T800xProtocolDecoder(null); + var decoder = inject(new T800xProtocolDecoder(null)); verifyAttributes(decoder, binary( "27271000247bd00860112047066487210407034238000005d7d17365e625ff640a730148")); diff --git a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java index 56af8830a..36c9d9148 100644 --- a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class TaipProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TaipProtocolDecoder(null); + var decoder = inject(new TaipProtocolDecoder(null)); verifyAttribute(decoder, text( ">RUS00,111220124402-3138067-06417623000012200FF,000000000000000000000000000,0000000111,15640422,00000,+25.5,00000,51;ID=CST3G0443;#IP1:089F;*34<"), diff --git a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java index c5de8e62a..b4617cb61 100644 --- a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TechTltProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TechTltProtocolDecoder(null); + var decoder = inject(new TechTltProtocolDecoder(null)); verifyPosition(decoder, text( "002422269*POS=Y,16:21:20,25/11/09,3809.8063N,01444.7438E,4.17,117.23,0.4,09,40076,56341\r\n"), diff --git a/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java index dc4afb784..36c3b578b 100644 --- a/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java @@ -10,7 +10,7 @@ public class TechtoCruzFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TechtoCruzFrameDecoder(); + var decoder = inject(new TechtoCruzFrameDecoder()); assertEquals( buffer("$$A35,RESPO|G33|8612345678910|CRUZ,*E3"), diff --git a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java index 4cef682b4..459401469 100644 --- a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TechtoCruzProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TechtoCruzProtocolDecoder(null); + var decoder = inject(new TechtoCruzProtocolDecoder(null)); verifyPosition(decoder, text( "$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6")); diff --git a/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java index f315e6432..98b2b80c4 100644 --- a/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TekFrameDecoder(); + var decoder = inject(new TekFrameDecoder()); verifyFrame( binary("020315048715E70861074028023219026200400A0340002C007F0009000000000000000000402842064028420641284206402844064128440640284406402844064028440641284406402844060010010C04052B000253000000000001060A0000000000000228330000FF0000FF360014B394"), diff --git a/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java index a371ffe6b..17910a8d6 100644 --- a/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TekProtocolDecoder(null); + var decoder = inject(new TekProtocolDecoder(null)); verifyPosition(decoder, binary( "0501E304E00E76086107502100455111492C33332C3137303935342E302C353235352E393933344E2C30303833322E34333935572C322E312C3133342E382C322C302E30302C302E302C302E302C3234303931352C30362C3C45")); diff --git a/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java index 8c3650f4e..9f36b3f96 100644 --- a/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TelemaxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TelemaxProtocolDecoder(null); + var decoder = inject(new TelemaxProtocolDecoder(null)); verifyNull(decoder, text( "%067374070128")); diff --git a/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java index 125b61d48..dc6cc58c6 100644 --- a/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TelicFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TelicFrameDecoder(); + var decoder = inject(new TelicFrameDecoder()); verifyFrame( binary("303032363230333339337c3232367c31307c303032303034303130"), diff --git a/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java index 03824d91b..214bb06c7 100644 --- a/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TelicProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TelicProtocolDecoder(null); + var decoder = inject(new TelicProtocolDecoder(null)); verifyNull(decoder, text( "0026355565071347499|206|01|001002008")); diff --git a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java index 7787907b6..d5c7fcdb0 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TeltonikaFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TeltonikaFrameDecoder(); + var decoder = inject(new TeltonikaFrameDecoder()); verifyFrame( binary("000F313233343536373839303132333435"), diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index c3c32369c..0ae4bbfa4 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TeltonikaProtocolDecoder(null, false); + var decoder = inject(new TeltonikaProtocolDecoder(null, false)); verifyNull(decoder, binary( "000F313233343536373839303132333435")); @@ -127,7 +127,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecodePhoto() throws Exception { - var decoder = new TeltonikaProtocolDecoder(null, false); + var decoder = inject(new TeltonikaProtocolDecoder(null, false)); verifyNull(decoder, binary( "000F313233343536373839303132333435")); @@ -147,7 +147,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeConnectionless() throws Exception { - var decoder = new TeltonikaProtocolDecoder(null, true); + var decoder = inject(new TeltonikaProtocolDecoder(null, true)); verifyPositions(decoder, false, binary( "0049cafe0122000f33353734353430373237313339373508010000015d3766f6a800003eef961ec6215e0063006d09003100070401000200f001c8000242381c18003201c7000000e10001")); diff --git a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java index 6f96f73ad..fc66f53bb 100644 --- a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TeraTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TeraTrackProtocolDecoder(null); + var decoder = inject(new TeraTrackProtocolDecoder(null)); verifyAttributes(decoder, text( "{\"MDeviceID\":\"022043756090\",\"DiviceType\":\"1\",\"DataType\":\"1\",\"DataLength\":\"69\",\"DateTime\":\"2022-03-09 10:56:01\",\"Latitude\":\"-6.846451\",\"Longitude\":\"39.316324\",\"LongitudeState\":\"1\",\"LatitudeState\":\"0\",\"Speed\":\"90\",\"Mileage\":\"0\",\"FenceAlarm\":\"0\",\"AreaAlarmID\":\"0\",\"LockCutOff\":\"0\",\"SealTampered\":\"0\",\"MessageAck\":\"1\",\"LockRope\":\"1\",\"LockStatus\":\"1\",\"LockOpen\":\"0\",\"PasswordError\":\"0\",\"CardNo\":\"60000644\",\"IllegalCard\":\"0\",\"LowPower\":\"0\",\"UnCoverBack\":\"0\",\"CoverStatus\":\"1\",\"LockStuck\":\"0\",\"Power\":\"79\",\"GSM\":\"16\",\"IMEI\":\"860922043756090\",\"Index\":\"20\",\"Slave\":[]}")); diff --git a/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java index ff808e667..2085112ec 100644 --- a/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ThinkPowerProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ThinkPowerProtocolDecoder(null); + var decoder = inject(new ThinkPowerProtocolDecoder(null)); verifyNull(decoder, binary( "0103002C01020F38363737333030353038323030343606544C3930344111522D312E302E31372E32303231303431300011C3")); diff --git a/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java index 39e7ed473..859dd4f89 100644 --- a/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ThinkRaceProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ThinkRaceProtocolDecoder(null); + var decoder = inject(new ThinkRaceProtocolDecoder(null)); verifyNull(decoder, binary( "48415349483031343730303134382C8000100134363030303134363139363239343806FF")); diff --git a/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java index 2185fda29..3bcc9994a 100644 --- a/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tk102ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tk102ProtocolDecoder(null); + var decoder = inject(new Tk102ProtocolDecoder(null)); verifyNull(decoder, buffer( "[\u00800000000000\u000821315452]")); diff --git a/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java index 57df2ac5b..87c3d9317 100644 --- a/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java @@ -9,7 +9,7 @@ public class Tk103FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tk103FrameDecoder(); + var decoder = inject(new Tk103FrameDecoder()); verifyFrame( binary("283836343735353535353535353535352C445733422C3133313131372C412C353536322E30323837304E2C30313334382E3038313934452C312E3539372C3232333730372C3239312E36352C2D302E31302C3429"), diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 321d0cb50..6c01c14f7 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tk103ProtocolDecoder(null); + var decoder = inject(new Tk103ProtocolDecoder(null)); verifyPosition(decoder, text( "(868822040452227,DW3B,150421,A,4154.51607N,45.78950E,0.050,103142,0.000,595.200,7,0)")); diff --git a/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java index b747fa960..40d9ff34d 100644 --- a/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Tlt2hProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tlt2hProtocolDecoder(null); + var decoder = inject(new Tlt2hProtocolDecoder(null)); verifyNull(decoder, text( "#860517049471362#MT700#0000#AUTO#1\r\n", diff --git a/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java index 54d66dac9..d6d1b7275 100644 --- a/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TlvProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TlvProtocolDecoder(null); + var decoder = inject(new TlvProtocolDecoder(null)); verifyNull(decoder, binary( "30430f383630323437303330303934333931ff10393233323132323030303834353433340f533636385f415f56312e30315f454eff1130303a30433a45373a30303a30303a30300132")); diff --git a/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java index 886470745..9cdcb6169 100644 --- a/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TmgFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TmgFrameDecoder(); + var decoder = inject(new TmgFrameDecoder()); verifyNull( decoder.decode(null, null, binary("2424242424"))); diff --git a/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java index 722df5306..6d3c36005 100644 --- a/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TmgProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TmgProtocolDecoder(null); + var decoder = inject(new TmgProtocolDecoder(null)); verifyPosition(decoder, text( "$loc,869309013800417,08032014,094459,1,2826.1956,N,07659.7690,E,0.0,2.5,4441,31,6,95,1,LLLL,NNTN,HH,0.15,0.26,HR38AU1389,0,SW0.1a")); diff --git a/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java index dbc7210e0..b49345a42 100644 --- a/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TopflytechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TopflytechProtocolDecoder(null); + var decoder = inject(new TopflytechProtocolDecoder(null)); verifyPosition(decoder, text( "(880316890094910BP00XG00b600000000L00074b54S00000000R0C0F0014000100f0130531152205A0706.1395S11024.0965E000.0251.25")); diff --git a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java index e8da93006..5e7ec1136 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class TopinProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TopinProtocolDecoder(null); + var decoder = inject(new TopinProtocolDecoder(null)); verifyNull(decoder, binary( "787801080D0A")); diff --git a/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java index 95949c51b..175c32848 100644 --- a/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TotemFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TotemFrameDecoder(); + var decoder = inject(new TotemFrameDecoder()); verifyFrame( binary("24243030323542423836323031303033373239343836313345"), diff --git a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java index e16774782..83498b5ac 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TotemProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TotemProtocolDecoder(null); + var decoder = inject(new TotemProtocolDecoder(null)); verifyPosition(decoder, text( "$$0112E5864606045334223|201112223514,-68.923106,-22.455926,$Cloud,1738,621,730,12100,0,0,255,0,40,40,0,0,255,|13")); diff --git a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java index def280b04..c4513cbdc 100644 --- a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tr20ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tr20ProtocolDecoder(null); + var decoder = inject(new Tr20ProtocolDecoder(null)); verifyPosition(decoder, text( "%%TR20GRANT,L,210602170135,N0951.1733W08356.7672,000,000,C80:F0,00020008,108,CFG:6980.00|")); diff --git a/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java index d3d35b356..96ddf4175 100644 --- a/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tr900ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tr900ProtocolDecoder(null); + var decoder = inject(new Tr900ProtocolDecoder(null)); verifyPosition(decoder, text( ">00001001,4,1,150626,131252,W05830.2978,S3137.2783,,00,348,18,00,003-000,0,3,11111011*3b!"), diff --git a/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java index caac520e1..10603db1c 100644 --- a/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TrackboxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TrackboxProtocolDecoder(null); + var decoder = inject(new TrackboxProtocolDecoder(null)); verifyNull(decoder, text( "a=connect&v=11&i=111111111111111")); diff --git a/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java index ef99527d7..7542b3456 100644 --- a/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TrakMateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TrakMateProtocolDecoder(null); + var decoder = inject(new TrakMateProtocolDecoder(null)); verifyPosition(decoder, text( "^TMSTP|352984083995323|116|13.07809|77.55979|131508|131118|0.0|146.51|7|0|71 -2 248|0|13.1|0.0|10.5|1|0|0|0|#")); diff --git a/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java index 80e6a6e81..a093d94e9 100644 --- a/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TramigoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TramigoFrameDecoder(); + var decoder = inject(new TramigoFrameDecoder()); verifyFrame( binary("8000ed2bb0009c000101bee000050b09633d925b5472616d69676f3a205472697020737461727465642c2053686f636b2053656e736f722c206174204b696e6720437265656b20526f61642d46726565746f776e205374726565742c20506f727420486172636f7572742c205269766572732c204e472c20342e37363336312c20372e30313836382c2030373a31383a333620536570203320454f46"), diff --git a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java index 8b556b356..c2d13d199 100644 --- a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TramigoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TramigoProtocolDecoder(null); + var decoder = inject(new TramigoProtocolDecoder(null)); verifyAttributes(decoder, binary( "8000c426b000a6000101c557037598050d5c8a595472616d69676f3a204d6f76696e672c20302e3132206b6d2045206f66204c617275742054696e2049736c616d6963205072696d617279205363686f6f6c2c2054616970696e672c20506572616b2c204d592c20342e38333134392c203130302e37333038352c204e572077697468207370656564203130206b6d2f682c2030303a34393a30382041756720392020454f46")); diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index 33d4e0124..6dc28d89e 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TrvProtocolDecoder(null); + var decoder = inject(new TrvProtocolDecoder(null)); verifyNull(decoder, text( "TRVAP00352121088015548")); diff --git a/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java index 5d0e86a3f..3f5c60daa 100644 --- a/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tt8850ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tt8850ProtocolDecoder(null); + var decoder = inject(new Tt8850ProtocolDecoder(null)); verifyPosition(decoder, text( "\u0000\u0004,007F,0,GTFRI,020102,867844000667538,4142726856,0,0,1,3,1.6,0,997.3,-66.830786,10.483394,20171212171418,0734,0004,041A,4220,69,20171212171657,FF61")); diff --git a/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java index 1cab0f8b1..de6f3a6ff 100644 --- a/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TytanProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TytanProtocolDecoder(null); + var decoder = inject(new TytanProtocolDecoder(null)); verifyPositions(decoder, binary( "B500192000001405125652CA9B1A325FC98D11A9990018020118FC0D")); diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java index fba8f7db4..72f5dadd8 100644 --- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TzoneProtocolDecoder(null); + var decoder = inject(new TzoneProtocolDecoder(null)); verifyAttributes(decoder, binary( "545a004d24240407010d0000018032100000031515090c052c2100000022030a033400201347000056860a03340020134700002feb0a03340020134700007d96000baa10211f01810127022d000001ebe00d0a")); diff --git a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java index 77afbb50f..534287e0a 100644 --- a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java @@ -8,7 +8,7 @@ public class UlbotechFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UlbotechFrameDecoder(); + var decoder = inject(new UlbotechFrameDecoder()); verifyFrame( binary("f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8"), diff --git a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java index b7c6d2d45..52f2520cc 100644 --- a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class UlbotechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UlbotechProtocolDecoder(null); + var decoder = inject(new UlbotechProtocolDecoder(null)); verifyPosition(decoder, binary( "f801010353323083177450a703f6f0010efe55a31a0923d01400050070007003040a42000004040070cca00506039b1876220f060800000000000000000725310553410c0c9e310d05310f4641100440311119411f00476101810f8000310487411f00480804203a14c009033320159310f8")); diff --git a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java index 8c12f48f7..3464a6fee 100644 --- a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class UproProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UproProtocolDecoder(null); + var decoder = inject(new UproProtocolDecoder(null)); verifyPosition(decoder, buffer( "*HQ201999999,BA&A1656512233362911356523660000230618&B0100060010&C00000<6<&F0000&R2405&V0109&W0000003E&K00100&T65&I54600027A00FCB6227A00FCA5727A00E955327A00E8B5327A00F9748&Y54600027A000000FCB6227A000000FCA5727A000000E955327A000000E8B5327A000000F9748&b00A7E81007607#")); diff --git a/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java index 753063d26..40776278d 100644 --- a/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class UuxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UuxProtocolDecoder(null); + var decoder = inject(new UuxProtocolDecoder(null)); verifyNull(decoder, binary( "81910b01ff")); diff --git a/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java index 59b6dbea9..105dc8339 100644 --- a/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class V680ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new V680ProtocolDecoder(null); + var decoder = inject(new V680ProtocolDecoder(null)); verifyPosition(decoder, text( "#867967020910610#01234567890#1#0000#AUT#1#0500000000120000#114.036291,E,22.665795,N,111.00,000.00#111116#193333##"), diff --git a/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java index b079346c9..042b66cae 100644 --- a/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class VisiontekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VisiontekProtocolDecoder(null); + var decoder = inject(new VisiontekProtocolDecoder(null)); verifyPosition(decoder, text( "$1,117,28,01,16,15,05,48,1725.0518N,07824.5298E,0620,11,0,185,2062,0,0,0,1,1,1,1,24,00.0000,00.3740,00.0000,VAJRA V1.00,A")); diff --git a/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java index d43176a45..25cc03781 100644 --- a/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class VnetProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VnetProtocolDecoder(null); + var decoder = inject(new VnetProtocolDecoder(null)); verifyNull(decoder, binary( "24240000140029111909062986818303379282604c452e322e30302ea32b020f0000d3552323")); diff --git a/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java index 91cc3d317..7d039dc8f 100644 --- a/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Vt200FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Vt200FrameDecoder(); + var decoder = inject(new Vt200FrameDecoder()); verifyFrame( binary("28631037309456208400340102dc0906171616454415760201144494473f920a0c0000030500200100417c1f383a9d1090510000006a00007000000e00180ee129"), diff --git a/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java index 791751c27..25ce5550a 100644 --- a/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Vt200ProtocolDecoder(null); + var decoder = inject(new Vt200ProtocolDecoder(null)); verifyPosition(decoder, binary( "28192030961807208200210101b919011818375801245774036424612500160917000003aa008800007b00aa3429")); diff --git a/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java index c03511160..e381153a2 100644 --- a/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java @@ -10,7 +10,7 @@ public class VtfmsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VtfmsFrameDecoder(); + var decoder = inject(new VtfmsFrameDecoder()); assertEquals( buffer("(863071010087648,0HK44,00,000,14,2,9,,A,114946,180313,11.0244,076.9768,282,000,00000,00000,K,0000128,1,12.8,,200,2.501,,4.001,0,0,0,0,0,0,0,,)105"), diff --git a/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java index 1d4fa7f21..4925d9769 100644 --- a/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class VtfmsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VtfmsProtocolDecoder(null); + var decoder = inject(new VtfmsProtocolDecoder(null)); verifyPosition(decoder, text( "(861359037432331,0EF87,00,0,21,2,01,,A,154559,230119,1101.4046,07656.3859,241,000,00078,00000,K,0000812,1,12.7,,,,,,1,0,0,0,1,1,1,+919566531111*+919994462226,)054"), diff --git a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java index 91bccb4c0..42464c6fe 100644 --- a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java @@ -8,7 +8,7 @@ public class WatchFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WatchFrameDecoder(); + var decoder = inject(new WatchFrameDecoder()); verifyFrame( binary("5b33472a3335323636313039303134333135302a303030412a4c4b2c302c302c3130305d"), diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 50baaa81a..4d908b750 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -12,7 +12,7 @@ public class WatchProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WatchProtocolDecoder(null); + var decoder = inject(new WatchProtocolDecoder(null)); verifyNull(decoder, binary( "5b5a4a2a3738393436383035303034323639322a303033342a303433392a4a58544b2c302c77617463685f375f32303232303532363039333935342c312c362c2321414d520a0c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c389814ffcd762fe49d50ae7a2e0cb528aefbf76911df05c2fbe17d050c2200cff77ef0df4d9b4ab9a4340c449814dbe7c63fa82bc3750d800cc48abbffddb0df8e8fda95e5980c49982ff6cf65f9377d02a39c3aaa0c389805f2ff42c1b80e0a0eb1dc0c2998e9defe15cfa3bdbe80d3540c7298c2f6d9239e3eae3c4a81660c490034dbfd513fedad0c2fc3900cc40039b7f71bb0657ba75558c40cd7813b97ff7219777ec7f401260c7d040003bff6f75fdb898a6ba1140cecd127f7f83357cb73a68a5f680cb081d4f6e749e6af8ed367bc480cec1815dfffd2dbed358112af320ccc21179fffbd17a3a61c133b380c920047defc72a784770ec0fe400c383c42f6faebe76fa736e9d1be0c4918e7decddc67ec9afd87ff220cc418e6bffe6cf6c9ac1f83c3900ca6cad1ffe3da24e1be3b547d03c00c6b00b8fee77f60a76d3e7d0292e20c2918b7bfff76387b793d3a36300c7d0400b7fff7f63ae513ac6f74de0c980016fbff7d01f9b30fca67c7220caa982ff6dbd7bf3d8dfed143ec0c44982fdfcb7b517e26f6ea52420c0ed19cfedb438f179d3fc50ec40c008ad2ffff635fe28dc1ec1f860c76cb7d05bffda53eaebe4d201ae20ccccaffbbfd3db4abb6ddf39d0e0c6b00acfeff406fe4a12661caf80c76982fbffffeb17b2f65472f300c7d04c24bf6ef1b10e47f73fc10b40c76036cfecd4e7837145a6a8e900ccccaf2beeba36fbaa36feb60640c7d0400dfffff73bfa3b87d0256a1700c7d04e4efd6efc23b651eb73e77780ccc1813ffffb39f6baa6f3195080c00007afffee0b9df6346ca08d00c6bca7d04feff4d64a7b56f9855da0c769819fbfd954ea5bd7d040ba6420c4c4c09bfffd5f6c57d01930e7d01220cc48a22dffe30bfcbaf08a795140c7d040433b7ff3cba5f3e336a40060cecbd2bfaf775bea7bde7e095ee0cc4caaef7fb623feeaab69eabc20c8c0021bffd1ea4a1b090175a920c7d046445fbdfc1abe910b0ca56160c7d0440cbd7ef03893c7f7d02e1a8c20c85e42dff5fdaa145759d326b5a0ccc4084f75f8eeb7b15e4eb4ff80c6bc22ef7d7eaf8df3b8ff678cc0cca4026f3cf7518fd731ceca3560cec041ffbe7655eaf822f04c4fe0c7d0478e3fbfcb5dfc8a81fdbb9e20cc418e6d7ff777f26affe37cc020cd7977cbff7d0aecb9727be6a0c0c00bde1f2d797fc8754ed09d4ae0cc498279f7e729fcb9eff70c1a60c7d0478e5bfffc67eef953fda69aa0c7200f1bbf7e891ef5a287cb5b80c983629fee5555f739f8a29279a0c76d103bef73f55a6bf89ba8ce40cc46424f6ded9a194167a067d05880cc4780efeffc37fae944d89bfb40c4464bffffb6dd54e8344394a5c0c49781ffffc653feaa31af59ac00cc464cebfd76ae4e8a55d5b5a4a2a3738393436383035303034323639322a303033352a303434332a4a58544b2c302c77617463685f375f32303232303532363039333935342c322c362c5f24fbbc0c7d04983effcfe35fbd8fff7ce6f60c448a1dfbd715bec3b42448e58a0c0e0421bf5f17ebc31a43301bc40c768ababf4f66cf629ee31fe9900c6b6426bf5f4eb7669dacc439140c945733bff9351e7d04ab6be54ef60ccc98bfbffbf67f63b78d8f42880c7d0400c6f7fffab5cbae8e8275da0c0097ffdefff5dfafb0c4727d04980ccc78d1f6ff1a6b7e37631059fa0c760045f3fd853fea877d03aa87440cc40022f7ffa8b5c58f6e80c58e0ccc4c1f9ffff32fa7af87de04560cb09801f6fdd32efcbdad9495b60c6b987d05bff72d61eb687d05a9f9e20cca57c7ffff6cb1fe3387ea596e0c629823dedfbfc50b97965e44ea0c4918ccbfd7cc75e59fff92e9ee0c8c78e7faff707ffda60ec3ada60c30c217befffcb8f3290f06d75e0c0e8a7bb7dff3eec7b7928ef6680c38ca1cdeff272ba012597d051a520c0018dfffeff27d01e369b3bcd7d80c98146eb2fc7f45c38e1ce53e120c3d5700ff7fd44bee28aa089d900c007157bffffe30302d7d0583585c0ccc5747bfe7f73cff7d02de1098240c7d047865f6feca71d70bdfaab6a20cecb946bfd966be74b61a06c6660c441612ffe7eb966a8c2886cf760ccc7827bffd653ff7980a62e9320c00ca98f7fc1b311a3986700cc20c490017bfff70cfe7bb455637320c6228afbf7e6da4c59763b693740cccc2b5fee1951975760e4a9dca0c0000faffdb255f6f86af4be6fc0cccc2ffdfff7d0225efbc847c42760cb48a8fdffbe23ff1a78782cbe60c7d04980cffff6e6dfc75a6c65a500ce62808bfff24f853748a9537400cb4004ebfeb6e70aa4314903e8c0cb46408ff72d62f44945f64897d040cccca7abfff2db5c6bfcc345e700c7d04c24dd6fd5f95638f78974a800cc4caffffffb17d01c36bdd7d047c2e0c7d0436d1f7f8917f83af7fc5c2180c070449f6fe570f128577c8c97d040c7d047813f6df3fd17d026b6790d1b80cc400c9d6d92dc56497843ed10a0c44986effffe13fef8eef7c717a0c7d049872bbfdad3abe2be0d60b240c4900adbf7d02dfa4ef960fdf23580c629845fefc5a650fbf8b0d4cda0c7d040076b7ef273fe78fce983ae40c4a00ded7ff629f7fab4531501c0c6200b7ffedf13fe6a68f01fb6c0cc49809f77fdb91517fb39e8ba00c760009bf7fd6afe7b46921f27a0cecbd1df6faf99120776e807d03fe0c98ca23fbff3749fb5ed3909c160cc44cbbbfffbd70e77d0367bc2e740c499816f77fe2ffe08edd7d048c9e0c940021beff1df0f1338c2f1a3a0c7d040083feebba1c756e5760c2200c94981dfffdf921b92b99909ba40c7d04984ebbdf7ff0c77d025a1fbfc00c7657b3ff77f4befcae2bf625640c62ca53f7fdb35f2e92af3bd5c60c7d049878bbdfc0dfc1bdaa1918000cc404bbbfefb41ee6b50a39bf180c767874f7fb8ee156320ee600020c69981cffffe0fff6bb2764acaa0cec781bfbff7d0324eb9b4b4d5d5b5a4a2a3738393436383035303034323639322a303033362a303433302a4a58544b2c302c77617463685f375f32303232303532363039333935342c332c362c73580c07ca4fbbfff5bec5abcfac465c0c0042a8beff316aed38fe4603dc0c7d04577d04fefdc929f7294ce7520c0c76984dfaff402fe68ebe113b000c7d0436a6fed465ff4f8d8e3306300c44e434f7f79e84abb8fa081be80c983636bef7e128bf7d03d34c71c80cd7982dffd54cac94536beab1320c058bd6bfff701fe69d1a39d1e80c76caedb77ffea0e47febb469440c0098b2bef5e55eed981672b1c40cd800d1bef4bda58daf7d01d309180c08cadffbfc31799f5613fab2da0c7d049828beffa5eea0bd09a14c2e0c0000e59feb5f9dff7f4945e98e0cc40046ffcfe57fb58f7d053dd9e20c7d040047d7ffd38f67aa9db8d38c0c7698d2df5fe2efc6bb0f5a18220c980367bbfd95dae73e3bf2b59a0c49813796fdf5efab9d3ed7d3d80c9800ebd7fdb831ae8f91811e920c7d04ca74bbff5cdcf45605c25f140c013e029fbfe7ffc299376b409a0c7510009e7d02010f68824cccead60cb13b00f7d5821e6c8d594a06880c75ec00f6e782e8f06b0c610d1a0cc09843dfef117fa5b3aef236f40cdcc208ffff4831f83703ca20c00cc09800bf7fd71eec9ba34e3c200c650f6bffd5bc4dbe7ec5b0f1d80c0d1c1f92ef917fa0b96023eac00c8efb1db6bfa42eed9f69051d4e0c8eff23b2fe4486d56ef44f702e0c8ebc1b9657d46eeea852ac337e0c8efb1f96d9877fc9b34c38f1540c121c2796df13577c727f8cedec0ca9107d05afdd6a9d957ab76c02560c121c2dd6bfd33fa5b844f27d02340cb11037b6e3962e6eaf52d6e7460c2b1c3db2dfe61eef9aad3dcc0a0c542e42d763e709fe723a83ae7c0c7cfa56bf7fedb8763c3f8ab2c00ca40022efff2411604d22a485e00c228adcbfdfcd748293c66b0bf20cb10f0097ff806dcf7a0a640d6e0c5a0400b7e3030ef4ae0a6046f80cb82812fe7b04d77e4bab11894a0c541c24b2dd53fea5891e3824420ca9fb26b2d7156fa485049cac420ca91c2d9edb2487526c2e2260fa0ca9bc25b65ff28e41a34232c0f00c8efb25b649e51ec39c0ae6703a0c70f425a6c820dfaf2f8124c8960c80f42794b323aed9ca9b6924be0cb93b278e3e8d929c36bb70b6360c587b27524f85857d056d214841660cda2f278b4c876eb3186e5acc540ce6832f6e3f0d82f81226e6dc3a0c0b922feff50a03d03c98ae28360c03d62befb54ab611de0c8addee0c84d626b7fdb4461556dc0153040c0b0f27ff5781c5c2b32f6762140c49bf2dfaf521969b702ecb11d80c7d050f27cfed75bfab95dc4af3180c011c3d8e7451df80a5cd0948080c7c2e35f2c7b0becca22e50769e0c7c1c3d965e628f46a9a58ae6100c7c2e3b965f4a6b5ebd1436b0b00c7c863eaedf18c7816cdeeed7e20c2b3e3df6b73952b2b1abc048a00c7cfb3db6cd67ae68cda18af9d60c2bff3e96df12ff61b39627cd580c7c863fd6cd810ee595d85ee6645d5b5a4a2a3738393436383035303034323639322a303033372a303433372a4a58544b2c302c77617463685f375f32303232303532363039333935342c342c362c0c7cff3fb65f812fe196dc62d8360c7c2e3db2de738fae9ca7c7236c0c2b2e3d96df6c1d775a3df5a47e0c7c3e3f96fe943dc07e81e170700c75503fb7d6a6197f1b08df85440c5a133ab6d6a0e68f3acb04b7b00cfa293fd6cfc20c390d5265d3c80c581347b278077d03dc22d9e49c680ce64d47924e8dcdffe9be19dc100cb90f4f9e612d2201961c2e111c0c003b4febb58a96c809ab5a71040ce6d759fbddba54b2aa9d9d983e0cc029576ecf1f703099d84994520c4029579e7d0281577073f5629dd80c5a2952b6fed177177d01e57d0175c20cd8647d044f7e3c58aba523ddb0720cb56753d3e9c6799f95938401f60c756414ff5f00fb57bc4d7e111c0c7c085573ef743ee19ca30057e00c752e5ab77e34eec69f3cbe53940c542e4d96d6e7ff03854a9506620c7cff55b6efca197610a86606180c7cfb55b67eb25f4b999c002bf20c7c107d03beeb451fad8d042492740cb8f05eb5ff664f679c1cc991c60ce1671bffd33d9445b57d0584c7d60c07781dfef5e3ee81b45ff8a8c80cc40072b7dfe6fe6e978257253a0cb1131fe6783035868e439b00d80c583b27b17ecb53dd165c3422180c703b2fbeb18d023e14d90304700c3cce2b93cdc2e6b3550a5546160cb13b3b72fe24273859059b52040c224d34edc742f6bb7c877d02b5940cb84d37cdcfcbc3f03a041cf4ac0ca4923a9f3b74e805b235cce8660c759000fbfd90565072aa7d03bb520cb592017f411dcbe80a0cc420360c09d6528fcf2e25b382ee46d75a0ce2e853d3cfb617fd7d023f05e0780c07cc3bbabfa9f6cec5aa48ac600c404208fb678a4cf16a9c09098c0cf14244fbdfc2afe7932fe57d02900c011c369e7d0264a8570a54f9a2e80cb1103daed6249fe59dc888c2ac0cb1103573c5f697be759923ecc80c705f7d059effaaa4b09b976f375a0c804223bbed89767d041693edab180cb49819d7eb5a8573bb10c951540c3c643af74f021f25b6dd3b7d02040c07982bd73fb31fe38f09a227a40c037610ff7d03c6058098fef936a80c03b808debbe055a1a71319128c0c6b8f2e9e3bb52d71c226d3141a0cdab82d7fa9d416167a1cb950020c03c32bb23ee9e3743f3b6853060cc02937adb5157d05f4a6960c1b680c4076365e6b754bda9394a7aa720c06293ef23313fb1b94bcc2c09a0ce676006bbd8e0417941b90d23c0cb9294f7d01fd3d65748cf6d1cc220c03767d035e3a65e6f2514ab1db060ce6d965bf4035f65c79a9e4446a0ce62921dbf46457b56cd65f6c500c584d6bba7ea8166edd6cf7693a0cb939227bfca25f82a7c4202f2e0c06ce2b9a4f0d95f39eb43c22840c06901eef6fd15fe48f452000e00c62023afbffb269beba0ee0ac540ce6ec00f37b8139f2026e80f1440c22501dfe7d017d03ed8c3ff6803f240cc48ae3b7fd725e63a347cd64100c0094f8efdeb0a9f35c83eb06b00c005d5b5a4a2a3738393436383035303034323639322a303033382a303433332a4a58544b2c302c77617463685f375f32303232303532363039333935342c352c362c6647deef2df57fb68fd76b660c44e43cbfefc0beec867d025c3f920cb4507d01ff6f42ee6c1f58a0db0e0c7d045701ff7f19f9f90fdff037c20c4404259efcd47d02a52b7ef6df0e0c7d04d128f3578db14779993109560ce1e41ecffd2851af49256b1ecc0c7d049837ffff707168db3dd1ac240cc09419f7f39a7d013d6ec1b4e55c0cc4881cff5f49f55fadc52285a40c06ce9ad7dbb8349b97031ac3b00c407d049d9bed74dfadad950eab560c06799ffac7a924b18bdf11c3d40c8054a2f777522e65be921a77240c8042a19bff706fe5b7e3e7d0360cd82840bff3f4fe429bea0081560c0064419fd9157f8b9c797e92c20cc47fe2b7d5e6ee45bf0524010e0c0894299e7d037e4553bcbbc0989e0c40501bbbdc926f8daf53885e0a0c80971ffee559f5bf98ed54cf140c00581abbffac75b88b14d5e3780c5a046dd66fd7bfe5b7ca749df40c403672bbcfe47ee797860ded5e0cb5502efb7ee2ffc7bbdc27d0880c44ca08fbf7031ecd9321d21ef40cdc9806fefde36f0699ad1569420c22cb1bfbdc974fcb900ab601440c00cb1cfbdfd2f7d2730b0b46680c0b4203dfef309fe0adc121e2080c225829feeb901f25b926343bae0c624204dfff4875b69ceda4df4c0c499886ffe7301e8e8bf9ef0a260cdce408dbef829fe45337e98d860c010800ef76088d8015f3b2c84e0c755c3ecfc898f50fbcdb9344220c7c7d03459349337d01e4949da1b4ec0c7cf046ae6e4a90df3552070a5e0c7cf045d23fbba0951147986eca0c7536426e6ef2ef0b7d01c22fd2960cb8284e9db92d40552988334f200cb8024acdbfea90d13b545fe35e0cb8f04d5e48659d48b97c1096140c7c084f79df4402702126bf358a0cb8a74d4def66535e145638d12e0c543e4d8edfa2531b15a340eb800cb83e4eafbd9031291a8563e4780c54a74ef1c7300da79aa94bb67d050cb8f04eba6fb0325813871511b80ce20ff6fffd404ed58ecf264c8e0c7c0f1cb3fe1a36fb7187c379d00c7c3e52f6727d0261ca8bdd1361b80cb8d64d9a4fb1cfe0aadaaa7d05c40c2b2e44b2bfb9b4dcad9d7d0200280c7c3b47d5db803fc2aee71a77f00c7c1343b2bfa06ee6ad3228f10a0c7c3b4a76477fe7650b0c809ca80c54d74b92dbc327134514d6126e0c7c5f4a8f4f74efaaa5cd0a43bc0c7c104bb64ff5ce604fa2028b680c7cff4aaec7f7a9394cc4c599e60cb8ce52eeb553d215a6a466b4120c750f4fae5f9816c04a0a3f751e0c75e04f73c58e96bb4b925a4c680cb80f4b6e3fe1635614bbdeccbc0c7c3b4faf7e825e42d473ee76800ce298578ffcb61f0af936387bbe0cb800e39bf62410681583e0d2b20cb4987d05ff7f297bf69eaf4cd8b40cb57815bf7f300fcffe9fae966a0cb497acd75fd37f648d00d141a00cc48af9fffe1a3b979b8f8573e80c29bff1bf4b94c6fd7c3eec075e0c7cce1f5d5b5a4a2a3738393436383035303034323639322a303033392a303065352a4a58544b2c302c77617463685f375f32303232303532363039333935342c362c362c8f5cf9f34fa6edceb18c0ca4ce436e7d02d329de94b63eb11a0cb894438f44cf753dbc1a83b4560cb8e44391eff729d4155a231bf40cb59443f373b4288492cd6e38160c5a42049bfec8678ad42bce0c560cb12e39fec3d1fe24b5572ee0be0cb1ce35fe33688455aa74e3ffa40cb1d635df4b704160ae864a7d03440cb10f3267dbf4a21d540ca1051c0cb11337724f8747f5547d054e91660cb1a73692df964f3bbb0758d41a0cfe05b60c314460297eae4185f20cad673ceb6dfa05ddbe0278d5de5d")); @@ -145,7 +145,7 @@ public class WatchProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeVoiceMessage() throws Exception { - var decoder = new WatchProtocolDecoder(null); + var decoder = inject(new WatchProtocolDecoder(null)); var mediaManager = mock(MediaManager.class); when(mediaManager.writeFile(any(), any(), any())).thenReturn("mock.amr"); diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 12724c32f..6953784fb 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WialonProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WialonProtocolDecoder(null); + var decoder = inject(new WialonProtocolDecoder(null)); verifyNull(decoder, text( "#L#2.0;42001300083;;CE45")); diff --git a/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java index 2e0d86a61..45c86ae1a 100644 --- a/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java @@ -8,7 +8,7 @@ public class WliFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WliFrameDecoder(); + var decoder = inject(new WliFrameDecoder()); verifyFrame( binary("0231000101bba758c900010034000500ff001001258fc9013e80ed00001183350101e20006003200090030000a0032000b003331000c0031000d00343438000e003530000f003100100031303800130032001b003134001c0033392c33352c32382c33382c34302c33372c33332c33382c33352c34322c33372c3335001d003130001e0038002300343235002400303100250031303432320026003336343733002700323800280037002900312c312c312c312c31302e3232352e3135312e3230342c36353533352c302c39392c39392c3235352c3235352c3235352c323535002a0030002c0030003000300032003000330031003400ff001c0214130502061b0101258fc9013e80ed000001e2000000000000004d004500302c323031392f30352f30322c30363a33333a30302c323031392f30352f30322c30363a32363a3230005a003000f100352c302c342c302c2d312c2d3100f2003300f3003100f50038363634323530333137303639323400f600312c302c302c3431322c3000f70038343437373200f80032312c31312c302c302c302c302c2c2c2c2c2c302c3000f9003300fa00393100fb0032313100fc0032313000ff00313535363737383533340003"), diff --git a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java index 77184f86a..e74b1df06 100644 --- a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WliProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WliProtocolDecoder(null); + var decoder = inject(new WliProtocolDecoder(null)); verifyNull(decoder, binary( "0232776c693a30343930333332303332343103")); diff --git a/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java index 85a878aef..a1cbfe737 100644 --- a/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java @@ -11,7 +11,7 @@ public class WondexFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WondexFrameDecoder(); + var decoder = inject(new WondexFrameDecoder()); assertNull( decoder.decode(null, null, binary("f0d70b0001ca9a3b"))); diff --git a/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java index 111cc9fbe..72ba8e163 100644 --- a/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WondexProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WondexProtocolDecoder(null); + var decoder = inject(new WondexProtocolDecoder(null)); verifyPosition(decoder, buffer( "2005010051,19990925063830,26.106181,44.440225,0,0,0,7,2,0.0,0,,,0")); diff --git a/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java index 10381168e..b901820fe 100644 --- a/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WristbandProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WristbandProtocolDecoder(null); + var decoder = inject(new WristbandProtocolDecoder(null)); verifyNotNull(decoder, binary( "000102004459583836383730343034343735303035357c56312e307c317c7b4630342331382c30372c332c3539303139322c33303a31382c30372c332c3539303139322c33307d0d0afffefc")); diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java index aeca95376..7209a423b 100644 --- a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Xexun2FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xexun2FrameDecoder(); + var decoder = inject(new Xexun2FrameDecoder()); verifyFrame( binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"), diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java index 9faccec01..840c38b52 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xexun2ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xexun2ProtocolDecoder(null); + var decoder = inject(new Xexun2ProtocolDecoder(null)); verifyPositions(decoder, false, binary( "faaf00140a5a8618810536243350005ed8e101005b64622880401b001482060864cc2296f840daa22aa884f008c87483c291efddc4f09fc2f49db3c058ef68005a9abe1ae8299d6449bac4e984e0c1d6baa8469d265ff2b60100cc00080000fb2e0013572a3600000002000000000000faaf")); diff --git a/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java b/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java index 43b8bdc0e..9bc39fc97 100644 --- a/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java @@ -8,7 +8,7 @@ public class XexunFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new XexunFrameDecoder(); + var decoder = inject(new XexunFrameDecoder()); verifyFrame( binary("4750524d432c3230353933352e3030302c412c353134302e343335302c4e2c3530312e303638362c452c302e30302c302e30302c3132313031352c30302c303030302e302c412a37302c462c2c696d65693a3335393538373031343731383339322c"), diff --git a/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java index d2caa9c55..f7599b4c3 100644 --- a/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -6,9 +6,9 @@ import org.traccar.ProtocolTest; public class XexunProtocolDecoderTest extends ProtocolTest { @Test - public void testDecode() throws Exception { + public void testDecodeSimple() throws Exception { - var decoder = new XexunProtocolDecoder(null, false); + var decoder = inject(new XexunProtocolDecoder(null, false)); verifyAttributes(decoder, text( "GPRMC,.000,A,0.000000,S,0.0000,W,0.00,0.00,,00,0000.0,A*55,L,,imei:353579010727036,")); @@ -53,7 +53,12 @@ public class XexunProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "GPRMC,043435.000,A,811.299200,S,11339.9500,E,0.93,29.52,160313,00,0000.0,A*65,F,,imei:359585014597923,")); - decoder = new XexunProtocolDecoder(null, true); + } + + @Test + public void testDecodeFull() throws Exception { + + var decoder = inject(new XexunProtocolDecoder(null, true)); verifyPosition(decoder, text( "171007160505,,GPRMC,160505.000,A,5323.4680,N,00252.4202,W,000.0,129.7,071017,,,A*7A,F,ACCStart, imei:864504031916915,10,41.1,F:4.28V,1,135,19824,234,15,0062,B7D5")); diff --git a/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java index f3a56a79d..db9c829aa 100644 --- a/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class XirgoProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeCustom() throws Exception { - var decoder = new XirgoProtocolDecoder(null); + var decoder = inject(new XirgoProtocolDecoder(null)); decoder.setForm("UID,EV,D,T,LT,LN,AL,GSPT,HD,SV,HP,BV,CQ,GS,SI,IG,OT"); @@ -31,7 +31,7 @@ public class XirgoProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeNew() throws Exception { - var decoder = new XirgoProtocolDecoder(null); + var decoder = inject(new XirgoProtocolDecoder(null)); verifyPosition(decoder, text( "$$352054058132185,4001,2017/04/21,00:01:05,32.54659,-116.90670,143.2,0,0,0,598,0.0,12,0.9,765840,7.0,14.5,19,1,1,0011,8.5,63.2,5,21999,184,255,671,207,100,185##")); @@ -59,7 +59,7 @@ public class XirgoProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeOld() throws Exception { - var decoder = new XirgoProtocolDecoder(null); + var decoder = inject(new XirgoProtocolDecoder(null)); verifyPosition(decoder, text( "$$354660046140722,6001,2013/01/22,15:36:18,25.80907,-80.32531,7.1,19,165.2,11,0.8,11.1,17,1,1,3.9,2##"), diff --git a/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java index 3197ba854..8ed175a74 100644 --- a/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xrb28ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xrb28ProtocolDecoder(null); + var decoder = inject(new Xrb28ProtocolDecoder(null)); verifyAttributes(decoder, text( "*SCOR,OM,123456789123456,Q0,412,80,28#")); diff --git a/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java index f8ddd35c3..007af984e 100644 --- a/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xt013ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xt013ProtocolDecoder(null); + var decoder = inject(new Xt013ProtocolDecoder(null)); verifyPosition(decoder, text( "TK,862950021650364,150131090859,+53.267863,+5.767363,0,38,12,0,F,204,08,C94,336C,24,,4.09,1,,,,,,,,"), diff --git a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java index 1b3f6fcbb..35cb3c3fa 100644 --- a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xt2400ProtocolDecoder(null); + var decoder = inject(new Xt2400ProtocolDecoder(null)); decoder.setConfig("\n:wycfg pcr[1] 012801030405060708090a1213c8545657585a656e7d2cd055595d5e71797a7b7c7e7f80818285866b\n"); diff --git a/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java index 1d29b1282..81afe53a3 100644 --- a/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class YwtProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new YwtProtocolDecoder(null); + var decoder = inject(new YwtProtocolDecoder(null)); verifyPosition(decoder, text( "%RP,1222102985:1,170509033842,E102.146563,N14.582175,,0,320,10,0,00-00-00-00-00-00-00-00-00-00-00-00,,1db2-02b3-52004,3>941.523-32,7>1,19>-16,20>30.9V")); -- cgit v1.2.3 From 0202dbf7258df8cbe8168ddc985e774b1cadf964 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 14:48:42 -0700 Subject: Decouple more tests from context --- src/main/java/org/traccar/BaseProtocolDecoder.java | 4 ++ src/main/java/org/traccar/BaseProtocolEncoder.java | 19 ++++- src/main/java/org/traccar/TrackerClient.java | 5 +- src/main/java/org/traccar/TrackerServer.java | 5 +- .../java/org/traccar/protocol/AdmProtocol.java | 3 +- .../java/org/traccar/protocol/AisProtocol.java | 3 +- .../org/traccar/protocol/AlematicsProtocol.java | 3 +- .../java/org/traccar/protocol/AnytrekProtocol.java | 3 +- .../java/org/traccar/protocol/ApelProtocol.java | 3 +- .../java/org/traccar/protocol/AplicomProtocol.java | 3 +- .../java/org/traccar/protocol/AppelloProtocol.java | 3 +- .../java/org/traccar/protocol/AquilaProtocol.java | 3 +- .../java/org/traccar/protocol/Ardi01Protocol.java | 3 +- .../java/org/traccar/protocol/ArknavProtocol.java | 3 +- .../org/traccar/protocol/ArknavX8Protocol.java | 3 +- .../java/org/traccar/protocol/ArmoliProtocol.java | 3 +- .../java/org/traccar/protocol/ArnaviProtocol.java | 3 +- .../java/org/traccar/protocol/AstraProtocol.java | 5 +- .../java/org/traccar/protocol/At2000Protocol.java | 3 +- .../java/org/traccar/protocol/AtrackProtocol.java | 5 +- .../java/org/traccar/protocol/AuroProtocol.java | 3 +- .../org/traccar/protocol/AustinNbProtocol.java | 3 +- .../java/org/traccar/protocol/AutoFonProtocol.java | 3 +- .../org/traccar/protocol/AutoGradeProtocol.java | 3 +- .../org/traccar/protocol/AutoTrackProtocol.java | 3 +- .../java/org/traccar/protocol/AvemaProtocol.java | 3 +- .../java/org/traccar/protocol/Avl301Protocol.java | 3 +- .../java/org/traccar/protocol/B2316Protocol.java | 3 +- .../java/org/traccar/protocol/BceProtocol.java | 3 +- .../org/traccar/protocol/BlackKiteProtocol.java | 3 +- .../java/org/traccar/protocol/BlueProtocol.java | 3 +- .../java/org/traccar/protocol/BoxProtocol.java | 3 +- .../java/org/traccar/protocol/C2stekProtocol.java | 3 +- .../java/org/traccar/protocol/CalAmpProtocol.java | 3 +- .../org/traccar/protocol/CarTrackProtocol.java | 3 +- .../java/org/traccar/protocol/CarcellProtocol.java | 3 +- .../java/org/traccar/protocol/CarscopProtocol.java | 3 +- .../java/org/traccar/protocol/CastelProtocol.java | 5 +- .../traccar/protocol/CastelProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/CautelaProtocol.java | 3 +- .../org/traccar/protocol/CellocatorProtocol.java | 5 +- .../java/org/traccar/protocol/CguardProtocol.java | 3 +- .../org/traccar/protocol/CityeasyProtocol.java | 3 +- .../org/traccar/protocol/ContinentalProtocol.java | 3 +- .../org/traccar/protocol/CradlepointProtocol.java | 3 +- .../java/org/traccar/protocol/DingtekProtocol.java | 3 +- .../java/org/traccar/protocol/DishaProtocol.java | 3 +- .../java/org/traccar/protocol/DmtHttpProtocol.java | 3 +- .../java/org/traccar/protocol/DmtProtocol.java | 3 +- .../java/org/traccar/protocol/DolphinProtocol.java | 3 +- .../java/org/traccar/protocol/Dsf22Protocol.java | 5 +- .../java/org/traccar/protocol/DualcamProtocol.java | 3 +- .../java/org/traccar/protocol/DwayProtocol.java | 3 +- .../org/traccar/protocol/EasyTrackProtocol.java | 3 +- .../java/org/traccar/protocol/EelinkProtocol.java | 5 +- .../java/org/traccar/protocol/EgtsProtocol.java | 3 +- .../java/org/traccar/protocol/EnforaProtocol.java | 5 +- .../java/org/traccar/protocol/EnnfuProtocol.java | 3 +- .../org/traccar/protocol/EnvotechProtocol.java | 3 +- .../java/org/traccar/protocol/EsealProtocol.java | 3 +- .../java/org/traccar/protocol/EskyProtocol.java | 5 +- .../org/traccar/protocol/ExtremTracProtocol.java | 3 +- .../org/traccar/protocol/FifotrackProtocol.java | 3 +- .../java/org/traccar/protocol/FlespiProtocol.java | 3 +- .../java/org/traccar/protocol/FlexApiProtocol.java | 3 +- .../org/traccar/protocol/FlexCommProtocol.java | 3 +- .../traccar/protocol/FlexibleReportProtocol.java | 3 +- .../org/traccar/protocol/FlextrackProtocol.java | 3 +- .../java/org/traccar/protocol/FoxProtocol.java | 3 +- .../java/org/traccar/protocol/FreedomProtocol.java | 3 +- .../org/traccar/protocol/FreematicsProtocol.java | 3 +- .../org/traccar/protocol/FutureWayProtocol.java | 3 +- .../java/org/traccar/protocol/GalileoProtocol.java | 3 +- .../traccar/protocol/GalileoProtocolDecoder.java | 6 +- .../java/org/traccar/protocol/GatorProtocol.java | 5 +- .../java/org/traccar/protocol/GenxProtocol.java | 3 +- .../java/org/traccar/protocol/Gl100Protocol.java | 5 +- .../java/org/traccar/protocol/Gl200Protocol.java | 8 +-- .../org/traccar/protocol/GlobalSatProtocol.java | 3 +- .../org/traccar/protocol/GlobalstarProtocol.java | 3 +- .../java/org/traccar/protocol/GnxProtocol.java | 3 +- .../java/org/traccar/protocol/GoSafeProtocol.java | 5 +- .../java/org/traccar/protocol/GotopProtocol.java | 3 +- .../java/org/traccar/protocol/Gps056Protocol.java | 3 +- .../java/org/traccar/protocol/Gps103Protocol.java | 5 +- .../java/org/traccar/protocol/GpsGateProtocol.java | 3 +- .../org/traccar/protocol/GpsMarkerProtocol.java | 3 +- .../java/org/traccar/protocol/GpsmtaProtocol.java | 3 +- .../java/org/traccar/protocol/GranitProtocol.java | 3 +- .../java/org/traccar/protocol/Gs100Protocol.java | 3 +- .../java/org/traccar/protocol/Gt02Protocol.java | 3 +- .../java/org/traccar/protocol/Gt06Protocol.java | 3 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 5 +- .../org/traccar/protocol/Gt06ProtocolEncoder.java | 9 ++- .../java/org/traccar/protocol/Gt30Protocol.java | 3 +- .../java/org/traccar/protocol/H02Protocol.java | 8 +-- .../org/traccar/protocol/H02ProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/HaicomProtocol.java | 3 +- .../java/org/traccar/protocol/HomtecsProtocol.java | 3 +- .../java/org/traccar/protocol/HoopoProtocol.java | 3 +- .../org/traccar/protocol/HuaShengProtocol.java | 3 +- .../java/org/traccar/protocol/HuabaoProtocol.java | 3 +- .../traccar/protocol/HuabaoProtocolEncoder.java | 5 +- .../org/traccar/protocol/HunterProProtocol.java | 3 +- .../java/org/traccar/protocol/IdplProtocol.java | 3 +- .../org/traccar/protocol/IntellitracProtocol.java | 3 +- .../java/org/traccar/protocol/IotmProtocol.java | 3 +- .../java/org/traccar/protocol/ItsProtocol.java | 3 +- .../java/org/traccar/protocol/Ivt401Protocol.java | 3 +- .../java/org/traccar/protocol/JidoProtocol.java | 3 +- .../org/traccar/protocol/JpKorjarProtocol.java | 3 +- .../java/org/traccar/protocol/Jt600Protocol.java | 3 +- .../java/org/traccar/protocol/KenjiProtocol.java | 3 +- .../java/org/traccar/protocol/KhdProtocol.java | 3 +- .../java/org/traccar/protocol/L100Protocol.java | 3 +- .../java/org/traccar/protocol/LacakProtocol.java | 3 +- .../java/org/traccar/protocol/LaipacProtocol.java | 5 +- .../traccar/protocol/LaipacProtocolDecoder.java | 3 +- .../java/org/traccar/protocol/LeafSpyProtocol.java | 3 +- .../java/org/traccar/protocol/M2cProtocol.java | 3 +- .../java/org/traccar/protocol/M2mProtocol.java | 3 +- .../java/org/traccar/protocol/MaestroProtocol.java | 3 +- .../org/traccar/protocol/ManPowerProtocol.java | 3 +- .../org/traccar/protocol/Mavlink2Protocol.java | 6 +- .../org/traccar/protocol/MegastekProtocol.java | 3 +- .../org/traccar/protocol/MeiligaoProtocol.java | 5 +- .../traccar/protocol/MeiligaoProtocolDecoder.java | 5 +- .../traccar/protocol/MeiligaoProtocolEncoder.java | 5 +- .../org/traccar/protocol/MeitrackProtocol.java | 5 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 3 +- .../traccar/protocol/MeitrackProtocolEncoder.java | 5 +- .../org/traccar/protocol/MictrackProtocol.java | 5 +- .../org/traccar/protocol/MilesmateProtocol.java | 3 +- .../org/traccar/protocol/MiniFinderProtocol.java | 3 +- .../org/traccar/protocol/Minifinder2Protocol.java | 3 +- .../org/traccar/protocol/MobilogixProtocol.java | 3 +- .../java/org/traccar/protocol/MoovboxProtocol.java | 3 +- .../java/org/traccar/protocol/MotorProtocol.java | 3 +- .../java/org/traccar/protocol/Mta6Protocol.java | 6 +- .../java/org/traccar/protocol/MtxProtocol.java | 3 +- .../java/org/traccar/protocol/MxtProtocol.java | 3 +- .../java/org/traccar/protocol/NavigilProtocol.java | 3 +- .../java/org/traccar/protocol/NavisProtocol.java | 3 +- .../java/org/traccar/protocol/NavisetProtocol.java | 3 +- .../org/traccar/protocol/NavtelecomProtocol.java | 3 +- .../java/org/traccar/protocol/NeosProtocol.java | 3 +- .../java/org/traccar/protocol/NetProtocol.java | 3 +- .../java/org/traccar/protocol/NiotProtocol.java | 3 +- .../java/org/traccar/protocol/NoranProtocol.java | 3 +- .../java/org/traccar/protocol/NvsProtocol.java | 3 +- .../java/org/traccar/protocol/NyitechProtocol.java | 3 +- .../org/traccar/protocol/ObdDongleProtocol.java | 3 +- .../java/org/traccar/protocol/OigoProtocol.java | 3 +- .../java/org/traccar/protocol/OkoProtocol.java | 3 +- .../org/traccar/protocol/OmnicommProtocol.java | 3 +- .../java/org/traccar/protocol/OpenGtsProtocol.java | 3 +- .../java/org/traccar/protocol/OrbcommProtocol.java | 6 +- .../java/org/traccar/protocol/OrionProtocol.java | 3 +- .../java/org/traccar/protocol/OsmAndProtocol.java | 3 +- .../java/org/traccar/protocol/OutsafeProtocol.java | 3 +- .../org/traccar/protocol/OwnTracksProtocol.java | 3 +- .../org/traccar/protocol/PacificTrackProtocol.java | 3 +- .../org/traccar/protocol/PathAwayProtocol.java | 3 +- .../org/traccar/protocol/PiligrimProtocol.java | 3 +- .../java/org/traccar/protocol/PluginProtocol.java | 3 +- .../java/org/traccar/protocol/PolteProtocol.java | 3 +- .../java/org/traccar/protocol/PortmanProtocol.java | 3 +- .../org/traccar/protocol/PretraceProtocol.java | 3 +- .../traccar/protocol/PretraceProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/PricolProtocol.java | 5 +- .../org/traccar/protocol/ProgressProtocol.java | 3 +- .../java/org/traccar/protocol/PstProtocol.java | 5 +- .../java/org/traccar/protocol/Pt215Protocol.java | 3 +- .../java/org/traccar/protocol/Pt3000Protocol.java | 3 +- .../java/org/traccar/protocol/Pt502Protocol.java | 3 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 3 +- .../java/org/traccar/protocol/Pt60Protocol.java | 3 +- .../java/org/traccar/protocol/R12wProtocol.java | 3 +- .../org/traccar/protocol/RaceDynamicsProtocol.java | 3 +- .../java/org/traccar/protocol/RadarProtocol.java | 3 +- .../java/org/traccar/protocol/RaveonProtocol.java | 3 +- .../java/org/traccar/protocol/RecodaProtocol.java | 3 +- .../org/traccar/protocol/RetranslatorProtocol.java | 3 +- .../java/org/traccar/protocol/RitiProtocol.java | 3 +- .../org/traccar/protocol/RoboTrackProtocol.java | 3 +- .../java/org/traccar/protocol/RstProtocol.java | 3 +- .../java/org/traccar/protocol/RuptelaProtocol.java | 3 +- .../java/org/traccar/protocol/S168Protocol.java | 3 +- .../org/traccar/protocol/SabertekProtocol.java | 3 +- .../java/org/traccar/protocol/SanavProtocol.java | 5 +- .../java/org/traccar/protocol/SanulProtocol.java | 3 +- .../java/org/traccar/protocol/SatsolProtocol.java | 3 +- .../java/org/traccar/protocol/SigfoxProtocol.java | 3 +- .../java/org/traccar/protocol/SiwiProtocol.java | 3 +- .../org/traccar/protocol/SkypatrolProtocol.java | 3 +- .../org/traccar/protocol/SmartSoleProtocol.java | 3 +- .../java/org/traccar/protocol/SmokeyProtocol.java | 3 +- .../org/traccar/protocol/SolarPoweredProtocol.java | 3 +- .../java/org/traccar/protocol/SpotProtocol.java | 3 +- .../org/traccar/protocol/StarLinkProtocol.java | 3 +- .../traccar/protocol/StarLinkProtocolDecoder.java | 5 +- .../java/org/traccar/protocol/StarcomProtocol.java | 3 +- .../java/org/traccar/protocol/StartekProtocol.java | 3 +- .../java/org/traccar/protocol/StbProtocol.java | 3 +- .../java/org/traccar/protocol/Stl060Protocol.java | 3 +- .../java/org/traccar/protocol/SuntechProtocol.java | 3 +- .../traccar/protocol/SuntechProtocolDecoder.java | 11 ++- .../org/traccar/protocol/SupermateProtocol.java | 3 +- .../java/org/traccar/protocol/SviasProtocol.java | 4 +- .../org/traccar/protocol/SwiftechProtocol.java | 3 +- .../java/org/traccar/protocol/T55Protocol.java | 5 +- .../org/traccar/protocol/T55ProtocolDecoder.java | 3 +- .../java/org/traccar/protocol/T57Protocol.java | 3 +- .../java/org/traccar/protocol/T800xProtocol.java | 3 +- .../org/traccar/protocol/TaipPrefixEncoder.java | 15 ++-- .../java/org/traccar/protocol/TaipProtocol.java | 5 +- .../java/org/traccar/protocol/TechTltProtocol.java | 3 +- .../org/traccar/protocol/TechtoCruzProtocol.java | 3 +- .../java/org/traccar/protocol/TekProtocol.java | 3 +- .../java/org/traccar/protocol/TelemaxProtocol.java | 3 +- .../java/org/traccar/protocol/TelicProtocol.java | 3 +- .../org/traccar/protocol/TeltonikaProtocol.java | 5 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 3 +- .../org/traccar/protocol/TeraTrackProtocol.java | 3 +- .../org/traccar/protocol/ThinkPowerProtocol.java | 3 +- .../org/traccar/protocol/ThinkRaceProtocol.java | 3 +- .../java/org/traccar/protocol/Tk102Protocol.java | 3 +- .../java/org/traccar/protocol/Tk103Protocol.java | 5 +- .../org/traccar/protocol/Tk103ProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/Tlt2hProtocol.java | 3 +- .../java/org/traccar/protocol/TlvProtocol.java | 3 +- .../java/org/traccar/protocol/TmgProtocol.java | 3 +- .../org/traccar/protocol/TopflytechProtocol.java | 3 +- .../java/org/traccar/protocol/TopinProtocol.java | 3 +- .../java/org/traccar/protocol/TotemProtocol.java | 3 +- .../java/org/traccar/protocol/Tr20Protocol.java | 5 +- .../java/org/traccar/protocol/Tr900Protocol.java | 5 +- .../org/traccar/protocol/TrackboxProtocol.java | 3 +- .../org/traccar/protocol/TrakMateProtocol.java | 3 +- .../java/org/traccar/protocol/TramigoProtocol.java | 3 +- .../java/org/traccar/protocol/TrvProtocol.java | 3 +- .../java/org/traccar/protocol/Tt8850Protocol.java | 3 +- .../java/org/traccar/protocol/TytanProtocol.java | 3 +- .../java/org/traccar/protocol/TzoneProtocol.java | 6 +- .../org/traccar/protocol/UlbotechProtocol.java | 3 +- .../java/org/traccar/protocol/UproProtocol.java | 3 +- .../java/org/traccar/protocol/UuxProtocol.java | 3 +- .../java/org/traccar/protocol/V680Protocol.java | 5 +- .../org/traccar/protocol/VisiontekProtocol.java | 3 +- .../java/org/traccar/protocol/VnetProtocol.java | 3 +- .../java/org/traccar/protocol/Vt200Protocol.java | 3 +- .../java/org/traccar/protocol/VtfmsProtocol.java | 8 +-- .../java/org/traccar/protocol/WatchProtocol.java | 3 +- .../java/org/traccar/protocol/WialonProtocol.java | 17 +++-- .../java/org/traccar/protocol/WliProtocol.java | 3 +- .../java/org/traccar/protocol/WondexProtocol.java | 8 +-- .../org/traccar/protocol/WristbandProtocol.java | 3 +- .../java/org/traccar/protocol/Xexun2Protocol.java | 3 +- .../java/org/traccar/protocol/XexunProtocol.java | 13 ++-- .../java/org/traccar/protocol/XirgoProtocol.java | 10 +-- .../java/org/traccar/protocol/Xrb28Protocol.java | 3 +- .../java/org/traccar/protocol/Xt013Protocol.java | 10 +-- .../java/org/traccar/protocol/Xt2400Protocol.java | 3 +- .../java/org/traccar/protocol/YwtProtocol.java | 3 +- src/test/java/org/traccar/BaseTest.java | 25 ++++++- .../traccar/protocol/AdmProtocolEncoderTest.java | 2 +- .../traccar/protocol/BceProtocolEncoderTest.java | 2 +- .../protocol/CastelProtocolEncoderTest.java | 2 +- .../protocol/CellocatorProtocolEncoderTest.java | 2 +- .../protocol/CityeasyProtocolEncoderTest.java | 2 +- .../protocol/EasyTrackProtocolEncoderTest.java | 4 +- .../protocol/EelinkProtocolEncoderTest.java | 19 ++++- .../traccar/protocol/EsealProtocolEncoderTest.java | 2 +- .../protocol/FifotrackProtocolEncoderTest.java | 2 +- .../protocol/GalileoProtocolEncoderTest.java | 2 +- .../protocol/GlobalSatProtocolEncoderTest.java | 8 +-- .../protocol/Gps103ProtocolEncoderTest.java | 4 +- .../traccar/protocol/Gt06ProtocolEncoderTest.java | 2 +- .../traccar/protocol/H02ProtocolEncoderTest.java | 10 ++- .../protocol/HuabaoProtocolEncoderTest.java | 2 +- .../traccar/protocol/ItsProtocolEncoderTest.java | 2 +- .../traccar/protocol/KhdProtocolEncoderTest.java | 2 +- .../protocol/MeiligaoProtocolEncoderTest.java | 2 +- .../protocol/MeitrackProtocolEncoderTest.java | 2 +- .../protocol/MiniFinderProtocolEncoderTest.java | 2 +- .../traccar/protocol/NoranProtocolEncoderTest.java | 2 +- .../protocol/PortmanProtocolEncoderTest.java | 8 +-- .../protocol/PretraceProtocolEncoderTest.java | 4 +- .../traccar/protocol/PstProtocolEncoderTest.java | 8 +-- .../traccar/protocol/Pt502ProtocolEncoderTest.java | 8 +-- .../protocol/RuptelaProtocolEncoderTest.java | 2 +- .../protocol/StartekProtocolEncoderTest.java | 4 +- .../traccar/protocol/T800xProtocolEncoderTest.java | 2 +- .../protocol/TeltonikaProtocolEncoderTest.java | 2 +- .../traccar/protocol/Tk103ProtocolEncoderTest.java | 80 +++++++++++----------- .../traccar/protocol/TopinProtocolEncoderTest.java | 2 +- .../traccar/protocol/TotemProtocolEncoderTest.java | 4 +- .../protocol/UlbotechProtocolEncoderTest.java | 4 +- .../traccar/protocol/WatchProtocolEncoderTest.java | 6 +- .../protocol/WondexProtocolEncoderTest.java | 2 +- .../traccar/protocol/XirgoProtocolEncoderTest.java | 2 +- .../traccar/protocol/Xrb28ProtocolEncoderTest.java | 8 +-- 302 files changed, 754 insertions(+), 479 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 0f62c87df..9a396bd64 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -78,6 +78,10 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { init(); } + public IdentityManager getIdentityManager() { + return identityManager; + } + @Inject public void setIdentityManager(IdentityManager identityManager) { this.identityManager = identityManager; diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 71fa61e4e..10b780fc8 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.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. @@ -15,12 +15,14 @@ */ package org.traccar; +import com.google.inject.Inject; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.database.IdentityManager; import org.traccar.helper.NetworkUtil; import org.traccar.model.Command; @@ -32,21 +34,32 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter private final Protocol protocol; + private IdentityManager identityManager; + public BaseProtocolEncoder(Protocol protocol) { this.protocol = protocol; } + public IdentityManager getIdentityManager() { + return identityManager; + } + + @Inject + public void setIdentityManager(IdentityManager identityManager) { + this.identityManager = identityManager; + } + public String getProtocolName() { return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; } protected String getUniqueId(long deviceId) { - return Context.getIdentityManager().getById(deviceId).getUniqueId(); + return identityManager.getById(deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - String password = Context.getIdentityManager() + String password = identityManager .getDevicePassword(command.getDeviceId(), getProtocolName(), defaultPassword); command.set(Command.KEY_DEVICE_PASSWORD, password); } diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index dda02f909..12971849c 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -23,6 +23,7 @@ import io.netty.handler.ssl.SslHandler; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GlobalEventExecutor; +import org.traccar.config.Config; import org.traccar.config.Keys; import javax.net.ssl.SSLContext; @@ -77,7 +78,7 @@ public abstract class TrackerClient implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { try { - TrackerClient.this.addProtocolHandlers(pipeline); + TrackerClient.this.addProtocolHandlers(pipeline, Context.getConfig()); } catch (Exception e) { throw new RuntimeException(e); } @@ -90,7 +91,7 @@ public abstract class TrackerClient implements TrackerConnector { .handler(pipelineFactory); } - protected abstract void addProtocolHandlers(PipelineBuilder pipeline) throws Exception; + protected abstract void addProtocolHandlers(PipelineBuilder pipeline, Config config) throws Exception; public String[] getDevices() { return devices; diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index 8e2fce616..b279d3479 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -25,6 +25,7 @@ import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.ssl.SslHandler; import io.netty.util.concurrent.GlobalEventExecutor; +import org.traccar.config.Config; import org.traccar.config.Keys; import javax.net.ssl.SSLContext; @@ -76,7 +77,7 @@ public abstract class TrackerServer implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - TrackerServer.this.addProtocolHandlers(pipeline); + TrackerServer.this.addProtocolHandlers(pipeline, Context.getConfig()); } }; @@ -97,7 +98,7 @@ public abstract class TrackerServer implements TrackerConnector { } } - protected abstract void addProtocolHandlers(PipelineBuilder pipeline); + protected abstract void addProtocolHandlers(PipelineBuilder pipeline, Config config); public int getPort() { return port; diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java index d1d81118c..8c5e2de0d 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocol.java +++ b/src/main/java/org/traccar/protocol/AdmProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class AdmProtocol extends BaseProtocol { @@ -29,7 +30,7 @@ public class AdmProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AdmFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new AdmProtocolEncoder(AdmProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AisProtocol.java b/src/main/java/org/traccar/protocol/AisProtocol.java index 3b9cad7c8..5697d7f3f 100644 --- a/src/main/java/org/traccar/protocol/AisProtocol.java +++ b/src/main/java/org/traccar/protocol/AisProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AisProtocol extends BaseProtocol { public AisProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new AisProtocolDecoder(AisProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocol.java b/src/main/java/org/traccar/protocol/AlematicsProtocol.java index 8da2356b9..1e68949ae 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AlematicsProtocol extends BaseProtocol { public AlematicsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AlematicsFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocol.java b/src/main/java/org/traccar/protocol/AnytrekProtocol.java index 9bd0c9163..8c020e64e 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocol.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class AnytrekProtocol extends BaseProtocol { public AnytrekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 2, 0, true)); pipeline.addLast(new AnytrekProtocolDecoder(AnytrekProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ApelProtocol.java b/src/main/java/org/traccar/protocol/ApelProtocol.java index 382aa16af..0c0d6279e 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocol.java +++ b/src/main/java/org/traccar/protocol/ApelProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class ApelProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class ApelProtocol extends BaseProtocol { public ApelProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast(new ApelProtocolDecoder(ApelProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AplicomProtocol.java b/src/main/java/org/traccar/protocol/AplicomProtocol.java index 2b9dbf97c..21556bd69 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocol.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AplicomProtocol extends BaseProtocol { public AplicomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AplicomFrameDecoder()); pipeline.addLast(new AplicomProtocolDecoder(AplicomProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AppelloProtocol.java b/src/main/java/org/traccar/protocol/AppelloProtocol.java index 1ca4168e4..919c8ab62 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocol.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AppelloProtocol extends BaseProtocol { public AppelloProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AquilaProtocol.java b/src/main/java/org/traccar/protocol/AquilaProtocol.java index 5ca1ec091..72161ccec 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocol.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AquilaProtocol extends BaseProtocol { public AquilaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Ardi01Protocol.java b/src/main/java/org/traccar/protocol/Ardi01Protocol.java index f7826430f..ba9dc9dfa 100644 --- a/src/main/java/org/traccar/protocol/Ardi01Protocol.java +++ b/src/main/java/org/traccar/protocol/Ardi01Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Ardi01Protocol extends BaseProtocol { public Ardi01Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index 3b485e4a5..76db3781c 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArknavProtocol extends BaseProtocol { public ArknavProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java index a29bc1ad3..55d2c58f9 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java +++ b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArknavX8Protocol extends BaseProtocol { public ArknavX8Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 5f36012af..70e70c89b 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArmoliProtocol extends BaseProtocol { public ArmoliProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";;", ";\r", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocol.java b/src/main/java/org/traccar/protocol/ArnaviProtocol.java index aecb42c8c..18af4e9be 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocol.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArnaviProtocol extends BaseProtocol { public ArnaviProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ArnaviFrameDecoder()); pipeline.addLast(new ArnaviProtocolDecoder(ArnaviProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AstraProtocol.java b/src/main/java/org/traccar/protocol/AstraProtocol.java index 12b0dfb68..c79c7f6fc 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocol.java +++ b/src/main/java/org/traccar/protocol/AstraProtocol.java @@ -19,20 +19,21 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AstraProtocol extends BaseProtocol { public AstraProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/At2000Protocol.java b/src/main/java/org/traccar/protocol/At2000Protocol.java index 5894f3eab..44bb11b94 100644 --- a/src/main/java/org/traccar/protocol/At2000Protocol.java +++ b/src/main/java/org/traccar/protocol/At2000Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class At2000Protocol extends BaseProtocol { public At2000Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new At2000FrameDecoder()); pipeline.addLast(new At2000ProtocolDecoder(At2000Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java index 429708b26..65cd5194e 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class AtrackProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class AtrackProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackFrameDecoder()); pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); @@ -35,7 +36,7 @@ public class AtrackProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AuroProtocol.java b/src/main/java/org/traccar/protocol/AuroProtocol.java index b8ebdaa75..f05b3f71c 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocol.java +++ b/src/main/java/org/traccar/protocol/AuroProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AuroProtocol extends BaseProtocol { public AuroProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocol.java b/src/main/java/org/traccar/protocol/AustinNbProtocol.java index 32bfc0aae..18a1c6c6a 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocol.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AustinNbProtocol extends BaseProtocol { public AustinNbProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new AustinNbProtocolDecoder(AustinNbProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocol.java b/src/main/java/org/traccar/protocol/AutoFonProtocol.java index 08b5edc7d..36d384c94 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AutoFonProtocol extends BaseProtocol { public AutoFonProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AutoFonFrameDecoder()); pipeline.addLast(new AutoFonProtocolDecoder(AutoFonProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java index c6dbb681e..c9d997163 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AutoGradeProtocol extends BaseProtocol { public AutoGradeProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java index 6aa7558bf..99a59fad7 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class AutoTrackProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class AutoTrackProtocol extends BaseProtocol { public AutoTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 5, 2, 2, 0, true)); pipeline.addLast(new AutoTrackProtocolDecoder(AutoTrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AvemaProtocol.java b/src/main/java/org/traccar/protocol/AvemaProtocol.java index dbfab4dea..69d2cbfa7 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocol.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AvemaProtocol extends BaseProtocol { public AvemaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Avl301Protocol.java b/src/main/java/org/traccar/protocol/Avl301Protocol.java index 71fc7cb26..bae4de7d0 100644 --- a/src/main/java/org/traccar/protocol/Avl301Protocol.java +++ b/src/main/java/org/traccar/protocol/Avl301Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Avl301Protocol extends BaseProtocol { public Avl301Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, -3, 0)); pipeline.addLast(new Avl301ProtocolDecoder(Avl301Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java index 7f08870ce..5b9d297f9 100644 --- a/src/main/java/org/traccar/protocol/B2316Protocol.java +++ b/src/main/java/org/traccar/protocol/B2316Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class B2316Protocol extends BaseProtocol { public B2316Protocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new B2316ProtocolDecoder(B2316Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java index c5e1dd04c..2d92894aa 100644 --- a/src/main/java/org/traccar/protocol/BceProtocol.java +++ b/src/main/java/org/traccar/protocol/BceProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class BceProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class BceProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new BceFrameDecoder()); pipeline.addLast(new BceProtocolEncoder(BceProtocol.this)); pipeline.addLast(new BceProtocolDecoder(BceProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java index 617a24d7a..e464b18d1 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java @@ -19,13 +19,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class BlackKiteProtocol extends BaseProtocol { public BlackKiteProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); pipeline.addLast(new BlackKiteProtocolDecoder(BlackKiteProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/BlueProtocol.java b/src/main/java/org/traccar/protocol/BlueProtocol.java index d5dc5c421..9d42e386e 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocol.java +++ b/src/main/java/org/traccar/protocol/BlueProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class BlueProtocol extends BaseProtocol { public BlueProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -2, 0)); pipeline.addLast(new BlueProtocolDecoder(BlueProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/BoxProtocol.java b/src/main/java/org/traccar/protocol/BoxProtocol.java index dfea15938..72a13c94a 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocol.java +++ b/src/main/java/org/traccar/protocol/BoxProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class BoxProtocol extends BaseProtocol { public BoxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/C2stekProtocol.java b/src/main/java/org/traccar/protocol/C2stekProtocol.java index 804621fd3..da490aedc 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocol.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class C2stekProtocol extends BaseProtocol { public C2stekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, false, "$AP")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocol.java b/src/main/java/org/traccar/protocol/CalAmpProtocol.java index 232e72a8c..056f23d01 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocol.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CalAmpProtocol extends BaseProtocol { public CalAmpProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CalAmpProtocolDecoder(CalAmpProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocol.java b/src/main/java/org/traccar/protocol/CarTrackProtocol.java index e340fba25..133fd8036 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CarTrackProtocol extends BaseProtocol { public CarTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java index f08ab3bd9..489b1d1de 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocol.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class CarcellProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class CarcellProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CarscopProtocol.java b/src/main/java/org/traccar/protocol/CarscopProtocol.java index 2c754a97f..d4c246c59 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocol.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CarscopProtocol extends BaseProtocol { public CarscopProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '^')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java index 44c52d68f..ee5432753 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocol.java +++ b/src/main/java/org/traccar/protocol/CastelProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.ByteOrder; @@ -30,7 +31,7 @@ public class CastelProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); @@ -38,7 +39,7 @@ public class CastelProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java index dc694da28..0fb4bf8b4 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java @@ -18,10 +18,9 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; import java.nio.charset.StandardCharsets; @@ -34,7 +33,7 @@ public class CastelProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(0); - String uniqueId = Context.getIdentityManager().getById(deviceId).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceId).getUniqueId(); buf.writeByte('@'); buf.writeByte('@'); diff --git a/src/main/java/org/traccar/protocol/CautelaProtocol.java b/src/main/java/org/traccar/protocol/CautelaProtocol.java index 452bdf8d4..13f3770b7 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocol.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CautelaProtocol extends BaseProtocol { public CautelaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java index d910877cf..6532848ac 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class CellocatorProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class CellocatorProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorFrameDecoder()); pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); @@ -35,7 +36,7 @@ public class CellocatorProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CguardProtocol.java b/src/main/java/org/traccar/protocol/CguardProtocol.java index 9157ca35c..ad5539fbd 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocol.java +++ b/src/main/java/org/traccar/protocol/CguardProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CguardProtocol extends BaseProtocol { public CguardProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java index 8ab4ce93a..28337bde9 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class CityeasyProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class CityeasyProtocol extends BaseProtocol { Command.TYPE_SET_TIMEZONE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast(new CityeasyProtocolEncoder(CityeasyProtocol.this)); pipeline.addLast(new CityeasyProtocolDecoder(CityeasyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocol.java b/src/main/java/org/traccar/protocol/ContinentalProtocol.java index bc7928fba..bbff3bda6 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocol.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ContinentalProtocol extends BaseProtocol { public ContinentalProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast(new ContinentalProtocolDecoder(ContinentalProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocol.java b/src/main/java/org/traccar/protocol/CradlepointProtocol.java index 4a09e0311..7d2270743 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocol.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CradlepointProtocol extends BaseProtocol { public CradlepointProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DingtekProtocol.java b/src/main/java/org/traccar/protocol/DingtekProtocol.java index cf2a6c0f5..7864d24df 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocol.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DingtekProtocol extends BaseProtocol { public DingtekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DingtekFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DishaProtocol.java b/src/main/java/org/traccar/protocol/DishaProtocol.java index 38f49cc05..c81c88c7c 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocol.java +++ b/src/main/java/org/traccar/protocol/DishaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DishaProtocol extends BaseProtocol { public DishaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java index 34568128f..107ec430c 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DmtHttpProtocol extends BaseProtocol { public DmtHttpProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/DmtProtocol.java b/src/main/java/org/traccar/protocol/DmtProtocol.java index 78a5243c0..d84099fac 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class DmtProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class DmtProtocol extends BaseProtocol { public DmtProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); pipeline.addLast(new DmtProtocolDecoder(DmtProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/DolphinProtocol.java b/src/main/java/org/traccar/protocol/DolphinProtocol.java index 07c827e18..1e67de8b2 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocol.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class DolphinProtocol extends BaseProtocol { public DolphinProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 4096, 20, 4, 4, 0, true)); pipeline.addLast(new DolphinProtocolDecoder(DolphinProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Dsf22Protocol.java b/src/main/java/org/traccar/protocol/Dsf22Protocol.java index bffc3e419..fcc7e7d55 100644 --- a/src/main/java/org/traccar/protocol/Dsf22Protocol.java +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.java @@ -18,20 +18,21 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Dsf22Protocol extends BaseProtocol { public Dsf22Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22FrameDecoder()); pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java index 04c4f2bd1..ba1dc0e4b 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DualcamProtocol extends BaseProtocol { public DualcamProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DualcamFrameDecoder()); pipeline.addLast(new DualcamProtocolDecoder(DualcamProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/DwayProtocol.java b/src/main/java/org/traccar/protocol/DwayProtocol.java index 05fd8b6e7..a729d6401 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocol.java +++ b/src/main/java/org/traccar/protocol/DwayProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DwayProtocol extends BaseProtocol { public DwayProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java index 972b36077..0c1fec7e8 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EasyTrackProtocol extends BaseProtocol { @@ -33,7 +34,7 @@ public class EasyTrackProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#\r\n", "#", "\r\n")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java index 8a055d643..654468ea0 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocol.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EelinkProtocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class EelinkProtocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, false)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); @@ -40,7 +41,7 @@ public class EelinkProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, true)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EgtsProtocol.java b/src/main/java/org/traccar/protocol/EgtsProtocol.java index 5d4638f37..fb17e41ae 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocol.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EgtsProtocol extends BaseProtocol { public EgtsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EgtsFrameDecoder()); pipeline.addLast(new EgtsProtocolDecoder(EgtsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java index e462ab322..5386787ea 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocol.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EnforaProtocol extends BaseProtocol { @@ -30,7 +31,7 @@ public class EnforaProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); @@ -38,7 +39,7 @@ public class EnforaProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocol.java b/src/main/java/org/traccar/protocol/EnnfuProtocol.java index 7ef94d83f..e72ff29ba 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocol.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EnnfuProtocol extends BaseProtocol { public EnnfuProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocol.java b/src/main/java/org/traccar/protocol/EnvotechProtocol.java index 8eb71ee6b..8ccf1776f 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocol.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EnvotechProtocol extends BaseProtocol { public EnvotechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java index fc1d342e1..e63e7ee5f 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocol.java +++ b/src/main/java/org/traccar/protocol/EsealProtocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EsealProtocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class EsealProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EskyProtocol.java b/src/main/java/org/traccar/protocol/EskyProtocol.java index fb047c207..dd81f4954 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocol.java +++ b/src/main/java/org/traccar/protocol/EskyProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EskyProtocol extends BaseProtocol { public EskyProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EskyFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -35,7 +36,7 @@ public class EskyProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java index 692fd4e99..4da56a8eb 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ExtremTracProtocol extends BaseProtocol { public ExtremTracProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java index 4a0a12ed3..7de8f3f62 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class FifotrackProtocol extends BaseProtocol { @@ -29,7 +30,7 @@ public class FifotrackProtocol extends BaseProtocol { Command.TYPE_REQUEST_PHOTO); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FifotrackFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new FifotrackProtocolEncoder(FifotrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FlespiProtocol.java b/src/main/java/org/traccar/protocol/FlespiProtocol.java index 05b105f93..874be7f68 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlespiProtocol extends BaseProtocol { public FlespiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder(4096, 8192, 128 * 1024)); pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE)); diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index 7f4154f71..87ae8e274 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -20,6 +20,7 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.charset.StandardCharsets; @@ -28,7 +29,7 @@ public class FlexApiProtocol extends BaseProtocol { public FlexApiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(5120)); pipeline.addLast(new StringDecoder(StandardCharsets.US_ASCII)); pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocol.java b/src/main/java/org/traccar/protocol/FlexCommProtocol.java index 9343ebeb8..6e6e59f24 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlexCommProtocol extends BaseProtocol { public FlexCommProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(2 + 2 + 101 + 5)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java index 0cd55343a..0d6437d83 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlexibleReportProtocol extends BaseProtocol { public FlexibleReportProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FlexibleReportProtocolDecoder(FlexibleReportProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocol.java b/src/main/java/org/traccar/protocol/FlextrackProtocol.java index ddd1d58f0..f80460477 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlextrackProtocol extends BaseProtocol { public FlextrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/FoxProtocol.java b/src/main/java/org/traccar/protocol/FoxProtocol.java index 9bac773b5..a91c2b2c5 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocol.java +++ b/src/main/java/org/traccar/protocol/FoxProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FoxProtocol extends BaseProtocol { public FoxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FreedomProtocol.java b/src/main/java/org/traccar/protocol/FreedomProtocol.java index bc6b92d5f..6a7a2d72e 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocol.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FreedomProtocol extends BaseProtocol { public FreedomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocol.java b/src/main/java/org/traccar/protocol/FreematicsProtocol.java index 999b075a1..0220b2030 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FreematicsProtocol extends BaseProtocol { public FreematicsProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new FreematicsProtocolDecoder(FreematicsProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocol.java b/src/main/java/org/traccar/protocol/FutureWayProtocol.java index 73b53ee12..7d2160345 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocol.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FutureWayProtocol extends BaseProtocol { public FutureWayProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FutureWayFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java index a1570c9b0..a3cda7fa1 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocol.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class GalileoProtocol extends BaseProtocol { @@ -28,7 +29,7 @@ public class GalileoProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); pipeline.addLast(new GalileoProtocolEncoder(GalileoProtocol.this)); pipeline.addLast(new GalileoProtocolDecoder(GalileoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index eb553c5a9..4c6d915d5 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -239,8 +238,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodePositions( - Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; @@ -322,7 +320,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index ca81caefb..a123b36ec 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -19,20 +19,21 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GatorProtocol extends BaseProtocol { public GatorProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/GenxProtocol.java b/src/main/java/org/traccar/protocol/GenxProtocol.java index c87ba946a..5bd89c512 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocol.java +++ b/src/main/java/org/traccar/protocol/GenxProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GenxProtocol extends BaseProtocol { public GenxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GenxProtocolDecoder(GenxProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gl100Protocol.java b/src/main/java/org/traccar/protocol/Gl100Protocol.java index 063e606db..91b039467 100644 --- a/src/main/java/org/traccar/protocol/Gl100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl100Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gl100Protocol extends BaseProtocol { public Gl100Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class Gl100Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java index e2d0c6d2a..4d74e3116 100644 --- a/src/main/java/org/traccar/protocol/Gl200Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java @@ -15,13 +15,13 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringEncoder; - public class Gl200Protocol extends BaseProtocol { public Gl200Protocol() { @@ -33,7 +33,7 @@ public class Gl200Protocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gl200FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); @@ -42,7 +42,7 @@ public class Gl200Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java index e86b5dc30..d5e3a483b 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class GlobalSatProtocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class GlobalSatProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "!\r\n", "!")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java index 84cd5565b..e829ff37e 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GlobalstarProtocol extends BaseProtocol { public GlobalstarProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/GnxProtocol.java b/src/main/java/org/traccar/protocol/GnxProtocol.java index 3576bf805..c51888336 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocol.java +++ b/src/main/java/org/traccar/protocol/GnxProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GnxProtocol extends BaseProtocol { public GnxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\n\r")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocol.java b/src/main/java/org/traccar/protocol/GoSafeProtocol.java index aaaffac97..35216436a 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocol.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GoSafeProtocol extends BaseProtocol { public GoSafeProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class GoSafeProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GoSafeProtocolDecoder(GoSafeProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GotopProtocol.java b/src/main/java/org/traccar/protocol/GotopProtocol.java index 07fe02248..e2fe4ff93 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocol.java +++ b/src/main/java/org/traccar/protocol/GotopProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GotopProtocol extends BaseProtocol { public GotopProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Gps056Protocol.java b/src/main/java/org/traccar/protocol/Gps056Protocol.java index b6ab10a19..fa7e5c12e 100644 --- a/src/main/java/org/traccar/protocol/Gps056Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps056Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gps056Protocol extends BaseProtocol { public Gps056Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gps056FrameDecoder()); pipeline.addLast(new Gps056ProtocolDecoder(Gps056Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java index 5356387ce..bf0b01526 100644 --- a/src/main/java/org/traccar/protocol/Gps103Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Gps103Protocol extends BaseProtocol { @@ -38,7 +39,7 @@ public class Gps103Protocol extends BaseProtocol { Command.TYPE_REQUEST_PHOTO); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -48,7 +49,7 @@ public class Gps103Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Gps103ProtocolEncoder(Gps103Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocol.java b/src/main/java/org/traccar/protocol/GpsGateProtocol.java index a131b6f48..51dbae7e3 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GpsGateProtocol extends BaseProtocol { public GpsGateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\0", "\n", "\r\n")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java index ad23ece48..3a0c1aeb9 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GpsMarkerProtocol extends BaseProtocol { public GpsMarkerProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java index ce6cc5929..68241958b 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GpsmtaProtocol extends BaseProtocol { public GpsmtaProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GpsmtaProtocolDecoder(GpsmtaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java index 244c3977b..58c3d1ba4 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocol.java +++ b/src/main/java/org/traccar/protocol/GranitProtocol.java @@ -19,6 +19,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class GranitProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class GranitProtocol extends BaseProtocol { Command.TYPE_POSITION_PERIODIC); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GranitFrameDecoder()); pipeline.addLast(new GranitProtocolEncoder(GranitProtocol.this)); pipeline.addLast(new GranitProtocolDecoder(GranitProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gs100Protocol.java b/src/main/java/org/traccar/protocol/Gs100Protocol.java index a701815d0..bd7c21b57 100644 --- a/src/main/java/org/traccar/protocol/Gs100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gs100Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gs100Protocol extends BaseProtocol { public Gs100Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gs100ProtocolDecoder(Gs100Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Gt02Protocol.java b/src/main/java/org/traccar/protocol/Gt02Protocol.java index f412ee720..c57de2fd6 100644 --- a/src/main/java/org/traccar/protocol/Gt02Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt02Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gt02Protocol extends BaseProtocol { public Gt02Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); pipeline.addLast(new Gt02ProtocolDecoder(Gt02Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java index 9ec8de098..48eb77c0c 100644 --- a/src/main/java/org/traccar/protocol/Gt06Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Gt06Protocol extends BaseProtocol { @@ -29,7 +30,7 @@ public class Gt06Protocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gt06FrameDecoder()); pipeline.addLast(new Gt06ProtocolEncoder(Gt06Protocol.this)); pipeline.addLast(new Gt06ProtocolDecoder(Gt06Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 832645374..22f38a497 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -1027,7 +1026,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); + Device device = getIdentityManager().getById(deviceSession.getDeviceId()); position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(pictureId).release(); } @@ -1263,7 +1262,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date(timestamp)); - Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); + Device device = getIdentityManager().getById(deviceSession.getDeviceId()); position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(mediaId).release(); } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 9115ba10f..3ed828fc7 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -18,10 +18,9 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; import java.nio.charset.StandardCharsets; @@ -33,7 +32,7 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, String content) { - boolean language = Context.getIdentityManager() + boolean language = getIdentityManager() .lookupAttributeBoolean(deviceId, getProtocolName() + ".language", false, false, true); ByteBuf buf = Unpooled.buffer(); @@ -66,10 +65,10 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); - String password = Context.getIdentityManager() + String password = getIdentityManager() .getDevicePassword(command.getDeviceId(), getProtocolName(), "123456"); switch (command.getType()) { diff --git a/src/main/java/org/traccar/protocol/Gt30Protocol.java b/src/main/java/org/traccar/protocol/Gt30Protocol.java index aa4ad20b1..da401acd1 100644 --- a/src/main/java/org/traccar/protocol/Gt30Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt30Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gt30Protocol extends BaseProtocol { public Gt30Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java index a5246abc6..d35333171 100644 --- a/src/main/java/org/traccar/protocol/H02Protocol.java +++ b/src/main/java/org/traccar/protocol/H02Protocol.java @@ -17,9 +17,9 @@ package org.traccar.protocol; import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; @@ -35,8 +35,8 @@ public class H02Protocol extends BaseProtocol { ); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - int messageLength = Context.getConfig().getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + int messageLength = config.getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); pipeline.addLast(new H02FrameDecoder(messageLength)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); @@ -45,7 +45,7 @@ public class H02Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 8f1a8c042..7fca0f93e 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -16,10 +16,9 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; -import org.traccar.Protocol; import java.util.Date; @@ -59,7 +58,7 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { return formatCommand(time, uniqueId, "S20", "1", "0"); case Command.TYPE_POSITION_PERIODIC: String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); - if (Context.getIdentityManager().lookupAttributeBoolean( + if (getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true)) { return formatCommand(time, uniqueId, "D1", frequency); } else { diff --git a/src/main/java/org/traccar/protocol/HaicomProtocol.java b/src/main/java/org/traccar/protocol/HaicomProtocol.java index 6e5760bd4..c03c3c0b3 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocol.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HaicomProtocol extends BaseProtocol { public HaicomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '*')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocol.java b/src/main/java/org/traccar/protocol/HomtecsProtocol.java index 34dbf0f51..85e4012a2 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocol.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HomtecsProtocol extends BaseProtocol { public HomtecsProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new HomtecsProtocolDecoder(HomtecsProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java index 387b967d3..8795ed727 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HoopoProtocol extends BaseProtocol { public HoopoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index 103f2d501..bf3b2052a 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HuaShengProtocol extends BaseProtocol { public HuaShengProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuaShengFrameDecoder()); pipeline.addLast(new HuaShengProtocolDecoder(HuaShengProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java index 791672b85..0e1ab0b02 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class HuabaoProtocol extends BaseProtocol { @@ -28,7 +29,7 @@ public class HuabaoProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); pipeline.addLast(new HuabaoProtocolEncoder(HuabaoProtocol.this)); pipeline.addLast(new HuabaoProtocolDecoder(HuabaoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java index 55c1e0c3b..82cf03b51 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -18,10 +18,9 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.model.Command; -import org.traccar.Protocol; import java.text.SimpleDateFormat; import java.util.Date; @@ -35,7 +34,7 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); ByteBuf id = Unpooled.wrappedBuffer( diff --git a/src/main/java/org/traccar/protocol/HunterProProtocol.java b/src/main/java/org/traccar/protocol/HunterProProtocol.java index 9f6424a57..e0f8bab28 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocol.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HunterProProtocol extends BaseProtocol { public HunterProProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IdplProtocol.java b/src/main/java/org/traccar/protocol/IdplProtocol.java index 418178756..5dda72c64 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocol.java +++ b/src/main/java/org/traccar/protocol/IdplProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class IdplProtocol extends BaseProtocol { public IdplProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocol.java b/src/main/java/org/traccar/protocol/IntellitracProtocol.java index 3abf40da7..c39be0fd0 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocol.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class IntellitracProtocol extends BaseProtocol { public IntellitracProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new IntellitracFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IotmProtocol.java b/src/main/java/org/traccar/protocol/IotmProtocol.java index f202d9b9d..b59d0ff3d 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocol.java +++ b/src/main/java/org/traccar/protocol/IotmProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.mqtt.MqttEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class IotmProtocol extends BaseProtocol { public IotmProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(MqttEncoder.INSTANCE); pipeline.addLast(new MqttDecoder()); pipeline.addLast(new IotmProtocolDecoder(IotmProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ItsProtocol.java b/src/main/java/org/traccar/protocol/ItsProtocol.java index 45df3da11..76097b20f 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocol.java +++ b/src/main/java/org/traccar/protocol/ItsProtocol.java @@ -20,6 +20,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class ItsProtocol extends BaseProtocol { @@ -30,7 +31,7 @@ public class ItsProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ItsFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Ivt401Protocol.java b/src/main/java/org/traccar/protocol/Ivt401Protocol.java index fb44e4fe9..2ef3ea2bf 100644 --- a/src/main/java/org/traccar/protocol/Ivt401Protocol.java +++ b/src/main/java/org/traccar/protocol/Ivt401Protocol.java @@ -20,13 +20,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Ivt401Protocol extends BaseProtocol { public Ivt401Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Ivt401ProtocolDecoder(Ivt401Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/JidoProtocol.java b/src/main/java/org/traccar/protocol/JidoProtocol.java index 2a2e71dbe..1040b45b9 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocol.java +++ b/src/main/java/org/traccar/protocol/JidoProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class JidoProtocol extends BaseProtocol { public JidoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java index fe5b2480d..c27dde8f1 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class JpKorjarProtocol extends BaseProtocol { public JpKorjarProtocol() { addServer(new TrackerServer(false, this.getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JpKorjarFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new JpKorjarProtocolDecoder(JpKorjarProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java index 37c82f741..7bc88de21 100644 --- a/src/main/java/org/traccar/protocol/Jt600Protocol.java +++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Jt600Protocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class Jt600Protocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Jt600FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Jt600ProtocolEncoder(Jt600Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/KenjiProtocol.java b/src/main/java/org/traccar/protocol/KenjiProtocol.java index 90c0c511c..91d5cf5b6 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocol.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocol.java @@ -22,13 +22,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class KenjiProtocol extends BaseProtocol { public KenjiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java index 60a2aea7f..835d4ea0b 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocol.java +++ b/src/main/java/org/traccar/protocol/KhdProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class KhdProtocol extends BaseProtocol { @@ -35,7 +36,7 @@ public class KhdProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2)); pipeline.addLast(new KhdProtocolEncoder(KhdProtocol.this)); pipeline.addLast(new KhdProtocolDecoder(KhdProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/L100Protocol.java b/src/main/java/org/traccar/protocol/L100Protocol.java index 942029307..44770c316 100644 --- a/src/main/java/org/traccar/protocol/L100Protocol.java +++ b/src/main/java/org/traccar/protocol/L100Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class L100Protocol extends BaseProtocol { public L100Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new L100FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/LacakProtocol.java b/src/main/java/org/traccar/protocol/LacakProtocol.java index 0a0499ad7..a22ba609d 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocol.java +++ b/src/main/java/org/traccar/protocol/LacakProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class LacakProtocol extends BaseProtocol { public LacakProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java index 1d561dbd2..973dcac06 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocol.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java @@ -18,10 +18,11 @@ package org.traccar.protocol; import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; -import org.traccar.model.Command; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; +import org.traccar.model.Command; public class LaipacProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class LaipacProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 45890e9a2..d8554dc13 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -253,7 +252,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { sendAcknowledge(status, event, checksum, channel, remoteAddress); - String devicePassword = Context.getIdentityManager() + String devicePassword = getIdentityManager() .getDevicePassword(deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); sendEventResponse(event, devicePassword, channel, remoteAddress); } diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java index 05f63a2d7..b121da2df 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -22,13 +22,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class LeafSpyProtocol extends BaseProtocol { public LeafSpyProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/M2cProtocol.java b/src/main/java/org/traccar/protocol/M2cProtocol.java index 9de8526c3..696823460 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocol.java +++ b/src/main/java/org/traccar/protocol/M2cProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class M2cProtocol extends BaseProtocol { public M2cProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, ']')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/M2mProtocol.java b/src/main/java/org/traccar/protocol/M2mProtocol.java index dda328a59..e21b61b91 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocol.java +++ b/src/main/java/org/traccar/protocol/M2mProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class M2mProtocol extends BaseProtocol { public M2mProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(23)); pipeline.addLast(new M2mProtocolDecoder(M2mProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MaestroProtocol.java b/src/main/java/org/traccar/protocol/MaestroProtocol.java index 87453ce7d..536f50448 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocol.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MaestroProtocol extends BaseProtocol { public MaestroProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(160)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocol.java b/src/main/java/org/traccar/protocol/ManPowerProtocol.java index 49d8b1e9f..8e640d137 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ManPowerProtocol extends BaseProtocol { public ManPowerProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java index d779648e4..6e92d0809 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java +++ b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java @@ -15,18 +15,18 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.config.Config; public class Mavlink2Protocol extends BaseProtocol { public Mavlink2Protocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 1, 10, 0)); pipeline.addLast(new Mavlink2ProtocolDecoder(Mavlink2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MegastekProtocol.java b/src/main/java/org/traccar/protocol/MegastekProtocol.java index e9f5f9fde..130697859 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocol.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MegastekProtocol extends BaseProtocol { public MegastekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MegastekFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index e8a66e49f..6ef13c51f 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class MeiligaoProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class MeiligaoProtocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoFrameDecoder()); pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); @@ -42,7 +43,7 @@ public class MeiligaoProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index a25cab06f..528098363 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -40,7 +39,7 @@ import java.util.regex.Pattern; public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { - private Map photos = new HashMap<>(); + private final Map photos = new HashMap<>(); public MeiligaoProtocolDecoder(Protocol protocol) { super(protocol); @@ -469,7 +468,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } else if (command == MSG_POSITION_IMAGE) { byte imageIndex = buf.readByte(); buf.readUnsignedByte(); // image upload type - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); ByteBuf photo = photos.remove(imageIndex); try { position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index e5b2cf4e7..7784ab093 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -18,11 +18,10 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.model.Command; -import org.traccar.Protocol; import java.nio.charset.StandardCharsets; import java.util.TimeZone; @@ -59,7 +58,7 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); int outputControlMessageType = alternative diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index 7439ea611..6503fa5e2 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class MeitrackProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class MeitrackProtocol extends BaseProtocol { Command.TYPE_SEND_SMS); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeitrackFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); @@ -43,7 +44,7 @@ public class MeitrackProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 6fed56fb6..3ab449350 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -204,7 +203,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); } - String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); + String deviceModel = getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); if (deviceModel == null) { deviceModel = ""; } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java index 354e81434..799e14ea2 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; import java.util.Map; @@ -42,7 +41,7 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { Map attributes = command.getAttributes(); - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); switch (command.getType()) { diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java index 9fd9666e4..0d1b26909 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MictrackProtocol extends BaseProtocol { public MictrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); @@ -34,7 +35,7 @@ public class MictrackProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocol.java b/src/main/java/org/traccar/protocol/MilesmateProtocol.java index 822711603..cc059c520 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocol.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MilesmateProtocol extends BaseProtocol { public MilesmateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index 0cc9598ed..182b5cd91 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class MiniFinderProtocol extends BaseProtocol { @@ -40,7 +41,7 @@ public class MiniFinderProtocol extends BaseProtocol { Command.TYPE_SET_INDICATOR); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\0", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index f8801db74..82341e9d0 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class Minifinder2Protocol extends BaseProtocol { public Minifinder2Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1200, 2, 2, 4, 0, true)); pipeline.addLast(new Minifinder2ProtocolDecoder(Minifinder2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index 28380a2af..37e3d9131 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocol.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MobilogixProtocol extends BaseProtocol { public MobilogixProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ']')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocol.java b/src/main/java/org/traccar/protocol/MoovboxProtocol.java index 7b554266f..00fcac6ed 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocol.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MoovboxProtocol extends BaseProtocol { public MoovboxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/MotorProtocol.java b/src/main/java/org/traccar/protocol/MotorProtocol.java index 680687e15..d168835bb 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocol.java +++ b/src/main/java/org/traccar/protocol/MotorProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MotorProtocol extends BaseProtocol { public MotorProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MotorProtocolDecoder(MotorProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Mta6Protocol.java b/src/main/java/org/traccar/protocol/Mta6Protocol.java index 14a66ce5c..689ee65dd 100644 --- a/src/main/java/org/traccar/protocol/Mta6Protocol.java +++ b/src/main/java/org/traccar/protocol/Mta6Protocol.java @@ -19,9 +19,9 @@ 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.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; public class Mta6Protocol extends BaseProtocol { @@ -29,12 +29,12 @@ public class Mta6Protocol extends BaseProtocol { public Mta6Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new Mta6ProtocolDecoder( - Mta6Protocol.this, !Context.getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getName())))); + Mta6Protocol.this, !config.getBoolean(Keys.PROTOCOL_CAN.withPrefix(getName())))); } }); } diff --git a/src/main/java/org/traccar/protocol/MtxProtocol.java b/src/main/java/org/traccar/protocol/MtxProtocol.java index 44372ce83..c22eb4b96 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocol.java +++ b/src/main/java/org/traccar/protocol/MtxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MtxProtocol extends BaseProtocol { public MtxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MxtProtocol.java b/src/main/java/org/traccar/protocol/MxtProtocol.java index dbe43fe45..8269f3f2c 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocol.java +++ b/src/main/java/org/traccar/protocol/MxtProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MxtProtocol extends BaseProtocol { public MxtProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MxtFrameDecoder()); pipeline.addLast(new MxtProtocolDecoder(MxtProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavigilProtocol.java b/src/main/java/org/traccar/protocol/NavigilProtocol.java index 2c946c39f..e5e3417e9 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocol.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavigilProtocol extends BaseProtocol { public NavigilProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavigilFrameDecoder()); pipeline.addLast(new NavigilProtocolDecoder(NavigilProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavisProtocol.java b/src/main/java/org/traccar/protocol/NavisProtocol.java index d5af6838d..146f0cc9f 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavisProtocol extends BaseProtocol { public NavisProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisFrameDecoder()); pipeline.addLast(new NavisProtocolDecoder(NavisProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java index 78755ea4d..6423dd401 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavisetProtocol extends BaseProtocol { public NavisetProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisetFrameDecoder()); pipeline.addLast(new NavisetProtocolDecoder(NavisetProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index 29ce8c41e..dfc08ece2 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavtelecomProtocol extends BaseProtocol { public NavtelecomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavtelecomFrameDecoder()); pipeline.addLast(new NavtelecomProtocolDecoder(NavtelecomProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NeosProtocol.java b/src/main/java/org/traccar/protocol/NeosProtocol.java index e545a9969..a3d79f833 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocol.java +++ b/src/main/java/org/traccar/protocol/NeosProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NeosProtocol extends BaseProtocol { public NeosProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new NeosProtocolDecoder(NeosProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/NetProtocol.java b/src/main/java/org/traccar/protocol/NetProtocol.java index c114d19fc..c39e07337 100644 --- a/src/main/java/org/traccar/protocol/NetProtocol.java +++ b/src/main/java/org/traccar/protocol/NetProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NetProtocol extends BaseProtocol { public NetProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '!')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/NiotProtocol.java b/src/main/java/org/traccar/protocol/NiotProtocol.java index b57b18a3a..659395638 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocol.java +++ b/src/main/java/org/traccar/protocol/NiotProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NiotProtocol extends BaseProtocol { public NiotProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new NiotProtocolDecoder(NiotProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java index 3df364c30..adeab8a75 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocol.java +++ b/src/main/java/org/traccar/protocol/NoranProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class NoranProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class NoranProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NoranProtocolEncoder(NoranProtocol.this)); pipeline.addLast(new NoranProtocolDecoder(NoranProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NvsProtocol.java b/src/main/java/org/traccar/protocol/NvsProtocol.java index d319b22f3..594b2c325 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocol.java +++ b/src/main/java/org/traccar/protocol/NvsProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NvsProtocol extends BaseProtocol { public NvsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NvsFrameDecoder()); pipeline.addLast(new NvsProtocolDecoder(NvsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NyitechProtocol.java b/src/main/java/org/traccar/protocol/NyitechProtocol.java index 58974be5c..da0a0331c 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocol.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class NyitechProtocol extends BaseProtocol { public NyitechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); pipeline.addLast(new NyitechProtocolDecoder(NyitechProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java index 10a55759b..b8ea7433a 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ObdDongleProtocol extends BaseProtocol { public ObdDongleProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1099, 20, 2, 3, 0)); pipeline.addLast(new ObdDongleProtocolDecoder(ObdDongleProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OigoProtocol.java b/src/main/java/org/traccar/protocol/OigoProtocol.java index 5056f68aa..02d5c40ff 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocol.java +++ b/src/main/java/org/traccar/protocol/OigoProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OigoProtocol extends BaseProtocol { public OigoProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OigoProtocolDecoder(OigoProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/OkoProtocol.java b/src/main/java/org/traccar/protocol/OkoProtocol.java index 9571ccc48..70ea65a29 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocol.java +++ b/src/main/java/org/traccar/protocol/OkoProtocol.java @@ -20,13 +20,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OkoProtocol extends BaseProtocol { public OkoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '}')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new OkoProtocolDecoder(OkoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocol.java b/src/main/java/org/traccar/protocol/OmnicommProtocol.java index 96660cb59..81a7b30ac 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocol.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OmnicommProtocol extends BaseProtocol { public OmnicommProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OmnicommFrameDecoder()); pipeline.addLast(new OmnicommProtocolDecoder(OmnicommProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java index 5ef3260c6..1eed96eed 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OpenGtsProtocol extends BaseProtocol { public OpenGtsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java index 2f9f56641..4f27b1efe 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocol.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -19,21 +19,21 @@ import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpResponseDecoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerClient; +import org.traccar.config.Config; public class OrbcommProtocol extends BaseProtocol { public OrbcommProtocol() { addClient(new TrackerClient(getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpRequestEncoder()); pipeline.addLast(new HttpResponseDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new OrbcommProtocolDecoder(OrbcommProtocol.this)); - pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this, Context.getConfig())); + pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this, config)); } }); } diff --git a/src/main/java/org/traccar/protocol/OrionProtocol.java b/src/main/java/org/traccar/protocol/OrionProtocol.java index 8485ae638..cb92f10b7 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocol.java +++ b/src/main/java/org/traccar/protocol/OrionProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OrionProtocol extends BaseProtocol { public OrionProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OrionFrameDecoder()); pipeline.addLast(new OrionProtocolDecoder(OrionProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocol.java b/src/main/java/org/traccar/protocol/OsmAndProtocol.java index d3aa2fd6f..3281a8ae4 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocol.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OsmAndProtocol extends BaseProtocol { public OsmAndProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocol.java b/src/main/java/org/traccar/protocol/OutsafeProtocol.java index c728a404d..ae7cb881f 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocol.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OutsafeProtocol extends BaseProtocol { public OutsafeProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java index 0086371d8..c444f453e 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java @@ -22,13 +22,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OwnTracksProtocol extends BaseProtocol { public OwnTracksProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java index 08991ab64..c8b046f41 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PacificTrackProtocol extends BaseProtocol { public PacificTrackProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PacificTrackProtocolDecoder(PacificTrackProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocol.java b/src/main/java/org/traccar/protocol/PathAwayProtocol.java index 6b5d75c5e..a2f152dda 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocol.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PathAwayProtocol extends BaseProtocol { public PathAwayProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocol.java b/src/main/java/org/traccar/protocol/PiligrimProtocol.java index d88c1ab72..7c0ecaf30 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocol.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PiligrimProtocol extends BaseProtocol { public PiligrimProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java index d5f28da9d..2d21f8b41 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocol.java +++ b/src/main/java/org/traccar/protocol/PluginProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PluginProtocol extends BaseProtocol { public PluginProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PolteProtocol.java b/src/main/java/org/traccar/protocol/PolteProtocol.java index a3e548716..47c64e5ba 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocol.java +++ b/src/main/java/org/traccar/protocol/PolteProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PolteProtocol extends BaseProtocol { public PolteProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/PortmanProtocol.java b/src/main/java/org/traccar/protocol/PortmanProtocol.java index b7faae08a..875c0a599 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocol.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class PortmanProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class PortmanProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java index 9d35c1c2f..db1b6d918 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocol.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class PretraceProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class PretraceProtocol extends BaseProtocol { Command.TYPE_POSITION_PERIODIC); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java index 1083a252e..106ba9537 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java @@ -16,10 +16,9 @@ package org.traccar.protocol; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; public class PretraceProtocolEncoder extends BaseProtocolEncoder { @@ -35,7 +34,7 @@ public class PretraceProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - String uniqueId = Context.getIdentityManager().getById(command.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(command.getDeviceId()).getUniqueId(); switch (command.getType()) { case Command.TYPE_CUSTOM: diff --git a/src/main/java/org/traccar/protocol/PricolProtocol.java b/src/main/java/org/traccar/protocol/PricolProtocol.java index 6821cd949..b009662ac 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocol.java +++ b/src/main/java/org/traccar/protocol/PricolProtocol.java @@ -19,20 +19,21 @@ import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PricolProtocol extends BaseProtocol { public PricolProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(64)); pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/ProgressProtocol.java b/src/main/java/org/traccar/protocol/ProgressProtocol.java index aac84205d..235ae1c5e 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocol.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class ProgressProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class ProgressProtocol extends BaseProtocol { public ProgressProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast(new ProgressProtocolDecoder(ProgressProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/PstProtocol.java b/src/main/java/org/traccar/protocol/PstProtocol.java index d8c7008cb..e1f3e18ce 100644 --- a/src/main/java/org/traccar/protocol/PstProtocol.java +++ b/src/main/java/org/traccar/protocol/PstProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class PstProtocol extends BaseProtocol { @@ -28,14 +29,14 @@ public class PstProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); pipeline.addLast(new PstProtocolDecoder(PstProtocol.this)); } }); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstFrameEncoder()); pipeline.addLast(new PstFrameDecoder()); pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java index 09bd9b121..c134afa51 100644 --- a/src/main/java/org/traccar/protocol/Pt215Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Pt215Protocol extends BaseProtocol { public Pt215Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 1, -1, 0)); pipeline.addLast(new Pt215ProtocolDecoder(Pt215Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Pt3000Protocol.java b/src/main/java/org/traccar/protocol/Pt3000Protocol.java index 1ad0026a3..1f783481b 100644 --- a/src/main/java/org/traccar/protocol/Pt3000Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt3000Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Pt3000Protocol extends BaseProtocol { public Pt3000Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java index 56444fb42..64ff4fe06 100644 --- a/src/main/java/org/traccar/protocol/Pt502Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Pt502Protocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class Pt502Protocol extends BaseProtocol { Command.TYPE_REQUEST_PHOTO); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Pt502FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Pt502ProtocolEncoder(Pt502Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index 5e24cacdc..0817d527d 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -175,7 +174,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/main/java/org/traccar/protocol/Pt60Protocol.java b/src/main/java/org/traccar/protocol/Pt60Protocol.java index c502426c5..45084a2f3 100644 --- a/src/main/java/org/traccar/protocol/Pt60Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt60Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Pt60Protocol extends BaseProtocol { public Pt60Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@", "@E#@")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/R12wProtocol.java b/src/main/java/org/traccar/protocol/R12wProtocol.java index 3726233b4..f3464a3a3 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocol.java +++ b/src/main/java/org/traccar/protocol/R12wProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class R12wProtocol extends BaseProtocol { public R12wProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java index c9db10610..7c7b9a87d 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RaceDynamicsProtocol extends BaseProtocol { public RaceDynamicsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1500)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/RadarProtocol.java b/src/main/java/org/traccar/protocol/RadarProtocol.java index 9783778f0..0b3d836a5 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocol.java +++ b/src/main/java/org/traccar/protocol/RadarProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RadarProtocol extends BaseProtocol { public RadarProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 12, 2, -14, 0)); pipeline.addLast(new RadarProtocolDecoder(RadarProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RaveonProtocol.java b/src/main/java/org/traccar/protocol/RaveonProtocol.java index 44faadb3b..5a1bb88d2 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocol.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RaveonProtocol extends BaseProtocol { public RaveonProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/RecodaProtocol.java b/src/main/java/org/traccar/protocol/RecodaProtocol.java index 0bc9870bc..9ae837a88 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocol.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class RecodaProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class RecodaProtocol extends BaseProtocol { public RecodaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 4, 4, -8, 0, true)); pipeline.addLast(new RecodaProtocolDecoder(RecodaProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java index fae81f7d2..efea6013e 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RetranslatorProtocol extends BaseProtocol { public RetranslatorProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RetranslatorFrameDecoder()); pipeline.addLast(new RetranslatorProtocolDecoder(RetranslatorProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RitiProtocol.java b/src/main/java/org/traccar/protocol/RitiProtocol.java index de1026672..34c4015b2 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocol.java +++ b/src/main/java/org/traccar/protocol/RitiProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class RitiProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class RitiProtocol extends BaseProtocol { public RitiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 105, 2, 3, 0, true)); pipeline.addLast(new RitiProtocolDecoder(RitiProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java index c2c531293..099136272 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RoboTrackProtocol extends BaseProtocol { public RoboTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RoboTrackFrameDecoder()); pipeline.addLast(new RoboTrackProtocolDecoder(RoboTrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java index 10d11d493..3a52a215e 100644 --- a/src/main/java/org/traccar/protocol/RstProtocol.java +++ b/src/main/java/org/traccar/protocol/RstProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RstProtocol extends BaseProtocol { public RstProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new RstProtocolDecoder(RstProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java index 5d1f86553..59c5f7942 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class RuptelaProtocol extends BaseProtocol { @@ -37,7 +38,7 @@ public class RuptelaProtocol extends BaseProtocol { Command.TYPE_SET_ODOMETER); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); pipeline.addLast(new RuptelaProtocolEncoder(RuptelaProtocol.this)); pipeline.addLast(new RuptelaProtocolDecoder(RuptelaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/S168Protocol.java b/src/main/java/org/traccar/protocol/S168Protocol.java index e78664c40..7186ce93d 100644 --- a/src/main/java/org/traccar/protocol/S168Protocol.java +++ b/src/main/java/org/traccar/protocol/S168Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class S168Protocol extends BaseProtocol { public S168Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SabertekProtocol.java b/src/main/java/org/traccar/protocol/SabertekProtocol.java index 0ec847b60..9c66fd50d 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocol.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SabertekProtocol extends BaseProtocol { public SabertekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SabertekFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new SabertekProtocolDecoder(SabertekProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SanavProtocol.java b/src/main/java/org/traccar/protocol/SanavProtocol.java index 6799c57e6..e067a2469 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocol.java +++ b/src/main/java/org/traccar/protocol/SanavProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SanavProtocol extends BaseProtocol { public SanavProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); @@ -34,7 +35,7 @@ public class SanavProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SanulProtocol.java b/src/main/java/org/traccar/protocol/SanulProtocol.java index 3104e9366..3c268d984 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocol.java +++ b/src/main/java/org/traccar/protocol/SanulProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class SanulProtocol extends BaseProtocol { public SanulProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); pipeline.addLast(new SanulProtocolDecoder(SanulProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SatsolProtocol.java b/src/main/java/org/traccar/protocol/SatsolProtocol.java index b69fdd1fe..15a43f94d 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocol.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class SatsolProtocol extends BaseProtocol { public SatsolProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1400, 8, 2, 0, 0, true)); pipeline.addLast(new SatsolProtocolDecoder(SatsolProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocol.java b/src/main/java/org/traccar/protocol/SigfoxProtocol.java index e2f2cbe1f..7666f5589 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocol.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SigfoxProtocol extends BaseProtocol { public SigfoxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/SiwiProtocol.java b/src/main/java/org/traccar/protocol/SiwiProtocol.java index 8963721c8..4cb441e8a 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocol.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SiwiProtocol extends BaseProtocol { public SiwiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new SiwiProtocolDecoder(SiwiProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java index 7c6203d86..91830504e 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SkypatrolProtocol extends BaseProtocol { public SkypatrolProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SkypatrolProtocolDecoder(SkypatrolProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java index bcf43f68b..6ae341db3 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SmartSoleProtocol extends BaseProtocol { public SmartSoleProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocol.java b/src/main/java/org/traccar/protocol/SmokeyProtocol.java index 482c8347c..dc7da9ab5 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocol.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SmokeyProtocol extends BaseProtocol { public SmokeyProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SmokeyProtocolDecoder(SmokeyProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java index 53a948cdc..9f9ef5a87 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SolarPoweredProtocol extends BaseProtocol { public SolarPoweredProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); pipeline.addLast(new SolarPoweredProtocolDecoder(SolarPoweredProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SpotProtocol.java b/src/main/java/org/traccar/protocol/SpotProtocol.java index bbf0e8d8a..238dc3b72 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocol.java +++ b/src/main/java/org/traccar/protocol/SpotProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SpotProtocol extends BaseProtocol { public SpotProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocol.java b/src/main/java/org/traccar/protocol/StarLinkProtocol.java index 5630722ee..fa9cdc30a 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocol.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class StarLinkProtocol extends BaseProtocol { public StarLinkProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 5e631017e..afccb3a6b 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; @@ -67,7 +66,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public String[] getFormat(long deviceId) { - return Context.getIdentityManager().lookupAttributeString( + return getIdentityManager().lookupAttributeString( deviceId, getProtocolName() + ".format", format, false, false).split(","); } @@ -76,7 +75,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public DateFormat getDateFormat(long deviceId) { - DateFormat dateFormat = new SimpleDateFormat(Context.getIdentityManager().lookupAttributeString( + DateFormat dateFormat = new SimpleDateFormat(getIdentityManager().lookupAttributeString( deviceId, getProtocolName() + ".dateFormat", this.dateFormat, false, false)); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); return dateFormat; diff --git a/src/main/java/org/traccar/protocol/StarcomProtocol.java b/src/main/java/org/traccar/protocol/StarcomProtocol.java index 63a6143a6..8f1c4bc3f 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocol.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class StarcomProtocol extends BaseProtocol { public StarcomProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StarcomProtocolDecoder(StarcomProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/StartekProtocol.java b/src/main/java/org/traccar/protocol/StartekProtocol.java index 32f1c5a29..14ae1564e 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocol.java +++ b/src/main/java/org/traccar/protocol/StartekProtocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class StartekProtocol extends BaseProtocol { @@ -33,7 +34,7 @@ public class StartekProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index 002ed86c7..206b29e29 100644 --- a/src/main/java/org/traccar/protocol/StbProtocol.java +++ b/src/main/java/org/traccar/protocol/StbProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class StbProtocol extends BaseProtocol { public StbProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Stl060Protocol.java b/src/main/java/org/traccar/protocol/Stl060Protocol.java index 2711e936b..0ac0490e3 100644 --- a/src/main/java/org/traccar/protocol/Stl060Protocol.java +++ b/src/main/java/org/traccar/protocol/Stl060Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Stl060Protocol extends BaseProtocol { public Stl060Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Stl060FrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java index 199885537..ae55d2a14 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocol.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class SuntechProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class SuntechProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SuntechFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SuntechProtocolEncoder(SuntechProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 8926f427e..fca7661f7 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -72,7 +71,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public int getProtocolType(long deviceId) { - return Context.getIdentityManager().lookupAttributeInteger( + return getIdentityManager().lookupAttributeInteger( deviceId, getProtocolName() + ".protocolType", protocolType, false, true); } @@ -81,7 +80,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isHbm(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".hbm", hbm, false, true); } @@ -90,7 +89,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeAdc(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".includeAdc", includeAdc, false, true); } @@ -99,7 +98,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeRpm(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".includeRpm", includeRpm, false, true); } @@ -108,7 +107,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeTemp(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".includeTemp", includeTemp, false, true); } diff --git a/src/main/java/org/traccar/protocol/SupermateProtocol.java b/src/main/java/org/traccar/protocol/SupermateProtocol.java index 46625ddc7..59c68d7d0 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocol.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SupermateProtocol extends BaseProtocol { public SupermateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java index accfa173f..d9b413a9e 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocol.java +++ b/src/main/java/org/traccar/protocol/SviasProtocol.java @@ -21,7 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - +import org.traccar.config.Config; import org.traccar.model.Command; public class SviasProtocol extends BaseProtocol { @@ -38,7 +38,7 @@ public class SviasProtocol extends BaseProtocol { Command.TYPE_ALARM_REMOVE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocol.java b/src/main/java/org/traccar/protocol/SwiftechProtocol.java index 5e2597b93..3222a7038 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocol.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SwiftechProtocol extends BaseProtocol { public SwiftechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/T55Protocol.java b/src/main/java/org/traccar/protocol/T55Protocol.java index f5ec19094..f3f7b4a74 100644 --- a/src/main/java/org/traccar/protocol/T55Protocol.java +++ b/src/main/java/org/traccar/protocol/T55Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class T55Protocol extends BaseProtocol { public T55Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); @@ -36,7 +37,7 @@ public class T55Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 230d29216..acfab5598 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -130,7 +129,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) - && Context.getIdentityManager().lookupAttributeBoolean( + && getIdentityManager().lookupAttributeBoolean( deviceSession.getDeviceId(), getProtocolName() + ".ack", false, false, true)) { channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); } diff --git a/src/main/java/org/traccar/protocol/T57Protocol.java b/src/main/java/org/traccar/protocol/T57Protocol.java index f67f82318..e228c5c0d 100644 --- a/src/main/java/org/traccar/protocol/T57Protocol.java +++ b/src/main/java/org/traccar/protocol/T57Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class T57Protocol extends BaseProtocol { public T57Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new T57FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index 8b91265cb..fa692c792 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class T800xProtocol extends BaseProtocol { @@ -28,7 +29,7 @@ public class T800xProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java b/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java index 02c111b01..48419af2a 100644 --- a/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java +++ b/src/main/java/org/traccar/protocol/TaipPrefixEncoder.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. @@ -15,13 +15,14 @@ */ package org.traccar.protocol; +import com.google.inject.Inject; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageEncoder; -import org.traccar.Context; import org.traccar.Protocol; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.util.List; @@ -30,14 +31,20 @@ import java.util.List; public class TaipPrefixEncoder extends MessageToMessageEncoder { private final Protocol protocol; + private Config config; public TaipPrefixEncoder(Protocol protocol) { this.protocol = protocol; } + @Inject + public void setConfig(Config config) { + this.config = config; + } + @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { - if (Context.getConfig().getBoolean(Keys.PROTOCOL_PREFIX.withPrefix(protocol.getName()))) { + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) { + if (config.getBoolean(Keys.PROTOCOL_PREFIX.withPrefix(protocol.getName()))) { out.add(Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(new byte[] {0x20, 0x20, 0x06, 0x00}), msg.retain())); } else { out.add(msg.retain()); diff --git a/src/main/java/org/traccar/protocol/TaipProtocol.java b/src/main/java/org/traccar/protocol/TaipProtocol.java index 0966cfd7c..caa4f4c97 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocol.java +++ b/src/main/java/org/traccar/protocol/TaipProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TaipProtocol extends BaseProtocol { public TaipProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '<')); pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); pipeline.addLast(new StringDecoder()); @@ -37,7 +38,7 @@ public class TaipProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java index 0cffb452d..e421990a7 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocol.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TechTltProtocol extends BaseProtocol { public TechTltProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new TechTltProtocolDecoder(TechTltProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java index a217ea738..48ea825a5 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TechtoCruzProtocol extends BaseProtocol { public TechtoCruzProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TechtoCruzFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TekProtocol.java b/src/main/java/org/traccar/protocol/TekProtocol.java index c1d78e6f5..0aeab9be3 100644 --- a/src/main/java/org/traccar/protocol/TekProtocol.java +++ b/src/main/java/org/traccar/protocol/TekProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TekProtocol extends BaseProtocol { public TekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TekFrameDecoder()); pipeline.addLast(new TekProtocolDecoder(TekProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocol.java b/src/main/java/org/traccar/protocol/TelemaxProtocol.java index 838da9df1..9bbdf7ad7 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocol.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TelemaxProtocol extends BaseProtocol { public TelemaxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TelicProtocol.java b/src/main/java/org/traccar/protocol/TelicProtocol.java index 991befa19..6d47a7a7f 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocol.java +++ b/src/main/java/org/traccar/protocol/TelicProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TelicProtocol extends BaseProtocol { public TelicProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TelicFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java index 5817b86be..e2ee8ef19 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class TeltonikaProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class TeltonikaProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaFrameDecoder()); pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); @@ -35,7 +36,7 @@ public class TeltonikaProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true)); } diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 407488527..03a5a00ea 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -149,7 +148,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { channel, remoteAddress, photoId, photo.writerIndex(), Math.min(IMAGE_PACKET_MAX, photo.writableBytes())); } else { - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(position.getDeviceId()).getUniqueId(); photos.remove(photoId); try { position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java index 0303b4b5a..8b62db8c0 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TeraTrackProtocol extends BaseProtocol { public TeraTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java index ece1b0544..076386818 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ThinkPowerProtocol extends BaseProtocol { public ThinkPowerProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, 2, 0)); pipeline.addLast(new ThinkPowerProtocolDecoder(ThinkPowerProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java index ca1237cef..6c684a8b4 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ThinkRaceProtocol extends BaseProtocol { public ThinkRaceProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2 + 12 + 1 + 1, 2, 2, 0)); pipeline.addLast(new ThinkRaceProtocolDecoder(ThinkRaceProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Tk102Protocol.java b/src/main/java/org/traccar/protocol/Tk102Protocol.java index 9f2463cd6..8eb923d50 100644 --- a/src/main/java/org/traccar/protocol/Tk102Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk102Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tk102Protocol extends BaseProtocol { public Tk102Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1 + 1 + 10, 1, 1, 0)); pipeline.addLast(new Tk102ProtocolDecoder(Tk102Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java index ff0bedfb7..bca16928f 100644 --- a/src/main/java/org/traccar/protocol/Tk103Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Tk103Protocol extends BaseProtocol { @@ -47,7 +48,7 @@ public class Tk103Protocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Tk103FrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); @@ -57,7 +58,7 @@ public class Tk103Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Tk103ProtocolEncoder(Tk103Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java index 5d7e63920..a0e9b199c 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -16,10 +16,9 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; -import org.traccar.Protocol; public class Tk103ProtocolEncoder extends StringProtocolEncoder { @@ -42,7 +41,7 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = forceAlternative || Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = forceAlternative || getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); initDevicePassword(command, "123456"); diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java index 12fd92afa..8c8777074 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tlt2hProtocol extends BaseProtocol { public Tlt2hProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TlvProtocol.java b/src/main/java/org/traccar/protocol/TlvProtocol.java index 94f5da94f..5b8de8fbe 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocol.java +++ b/src/main/java/org/traccar/protocol/TlvProtocol.java @@ -19,13 +19,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TlvProtocol extends BaseProtocol { public TlvProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); pipeline.addLast(new TlvProtocolDecoder(TlvProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TmgProtocol.java b/src/main/java/org/traccar/protocol/TmgProtocol.java index 020332ce7..6c29a8854 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocol.java +++ b/src/main/java/org/traccar/protocol/TmgProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TmgProtocol extends BaseProtocol { public TmgProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TmgFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocol.java b/src/main/java/org/traccar/protocol/TopflytechProtocol.java index 303072bdb..47162a42d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocol.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TopflytechProtocol extends BaseProtocol { public TopflytechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index d28afbf94..3c1a7eed3 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocol.java +++ b/src/main/java/org/traccar/protocol/TopinProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class TopinProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class TopinProtocol extends BaseProtocol { Command.TYPE_SOS_NUMBER); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TopinProtocolEncoder(TopinProtocol.this)); pipeline.addLast(new TopinProtocolDecoder(TopinProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index 417a4d6b0..3322d1dc0 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -20,6 +20,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class TotemProtocol extends BaseProtocol { @@ -48,7 +49,7 @@ public class TotemProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TotemFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tr20Protocol.java b/src/main/java/org/traccar/protocol/Tr20Protocol.java index 1b71db03f..dc6c013c8 100644 --- a/src/main/java/org/traccar/protocol/Tr20Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr20Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tr20Protocol extends BaseProtocol { public Tr20Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class Tr20Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr20ProtocolDecoder(Tr20Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Tr900Protocol.java b/src/main/java/org/traccar/protocol/Tr900Protocol.java index b70521b35..615987952 100644 --- a/src/main/java/org/traccar/protocol/Tr900Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr900Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tr900Protocol extends BaseProtocol { public Tr900Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class Tr900Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocol.java b/src/main/java/org/traccar/protocol/TrackboxProtocol.java index 5da5abd64..1c756e26b 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocol.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TrackboxProtocol extends BaseProtocol { public TrackboxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocol.java b/src/main/java/org/traccar/protocol/TrakMateProtocol.java index bda5df10f..25f6d9470 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocol.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TrakMateProtocol extends BaseProtocol { public TrakMateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TramigoProtocol.java b/src/main/java/org/traccar/protocol/TramigoProtocol.java index f683ccc5d..2c8013523 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocol.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TramigoProtocol extends BaseProtocol { public TramigoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TramigoFrameDecoder()); pipeline.addLast(new TramigoProtocolDecoder(TramigoProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TrvProtocol.java b/src/main/java/org/traccar/protocol/TrvProtocol.java index 99a164cf1..a8884eb5e 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocol.java +++ b/src/main/java/org/traccar/protocol/TrvProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TrvProtocol extends BaseProtocol { public TrvProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tt8850Protocol.java b/src/main/java/org/traccar/protocol/Tt8850Protocol.java index 66a13da9e..b11411817 100644 --- a/src/main/java/org/traccar/protocol/Tt8850Protocol.java +++ b/src/main/java/org/traccar/protocol/Tt8850Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tt8850Protocol extends BaseProtocol { public Tt8850Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "$")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TytanProtocol.java b/src/main/java/org/traccar/protocol/TytanProtocol.java index 32e9acae1..2ca1ff8e8 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocol.java +++ b/src/main/java/org/traccar/protocol/TytanProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TytanProtocol extends BaseProtocol { public TytanProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TytanProtocolDecoder(TytanProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/TzoneProtocol.java b/src/main/java/org/traccar/protocol/TzoneProtocol.java index 6e855d138..9bb550e39 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocol.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocol.java @@ -15,18 +15,18 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.config.Config; public class TzoneProtocol extends BaseProtocol { public TzoneProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 2, 2, 0)); pipeline.addLast(new TzoneProtocolDecoder(TzoneProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocol.java b/src/main/java/org/traccar/protocol/UlbotechProtocol.java index dfe5235f0..d149bbd58 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocol.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class UlbotechProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class UlbotechProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new UlbotechFrameDecoder()); pipeline.addLast(new UlbotechProtocolEncoder(UlbotechProtocol.this)); pipeline.addLast(new UlbotechProtocolDecoder(UlbotechProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/UproProtocol.java b/src/main/java/org/traccar/protocol/UproProtocol.java index 4e60ffeb6..5bfa6d76d 100644 --- a/src/main/java/org/traccar/protocol/UproProtocol.java +++ b/src/main/java/org/traccar/protocol/UproProtocol.java @@ -20,13 +20,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class UproProtocol extends BaseProtocol { public UproProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new UproProtocolDecoder(UproProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/UuxProtocol.java b/src/main/java/org/traccar/protocol/UuxProtocol.java index 41b59d829..61f622f68 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocol.java +++ b/src/main/java/org/traccar/protocol/UuxProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class UuxProtocol extends BaseProtocol { public UuxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 1)); pipeline.addLast(new UuxProtocolDecoder(UuxProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/V680Protocol.java b/src/main/java/org/traccar/protocol/V680Protocol.java index dc0922cd4..488dcc4e0 100644 --- a/src/main/java/org/traccar/protocol/V680Protocol.java +++ b/src/main/java/org/traccar/protocol/V680Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class V680Protocol extends BaseProtocol { public V680Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); @@ -36,7 +37,7 @@ public class V680Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocol.java b/src/main/java/org/traccar/protocol/VisiontekProtocol.java index 2c6af45a8..5d3e3c097 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocol.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class VisiontekProtocol extends BaseProtocol { public VisiontekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/VnetProtocol.java b/src/main/java/org/traccar/protocol/VnetProtocol.java index 0fed30e13..41522935e 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocol.java +++ b/src/main/java/org/traccar/protocol/VnetProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class VnetProtocol extends BaseProtocol { public VnetProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1500, 4, 2, 12, 0, true)); pipeline.addLast(new VnetProtocolDecoder(VnetProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Vt200Protocol.java b/src/main/java/org/traccar/protocol/Vt200Protocol.java index 2a9ef6ab5..655514e94 100644 --- a/src/main/java/org/traccar/protocol/Vt200Protocol.java +++ b/src/main/java/org/traccar/protocol/Vt200Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Vt200Protocol extends BaseProtocol { public Vt200Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Vt200FrameDecoder()); pipeline.addLast(new Vt200ProtocolDecoder(Vt200Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocol.java b/src/main/java/org/traccar/protocol/VtfmsProtocol.java index 2826a86e6..8bedd455d 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocol.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocol.java @@ -15,18 +15,18 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - -import io.netty.handler.codec.string.StringDecoder; +import org.traccar.config.Config; public class VtfmsProtocol extends BaseProtocol { public VtfmsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new VtfmsFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); @@ -34,7 +34,7 @@ public class VtfmsProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java index 6dc3bf9fb..fe96b3828 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocol.java +++ b/src/main/java/org/traccar/protocol/WatchProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class WatchProtocol extends BaseProtocol { @@ -42,7 +43,7 @@ public class WatchProtocol extends BaseProtocol { Command.TYPE_SET_INDICATOR); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WatchFrameDecoder()); pipeline.addLast(new WatchProtocolEncoder(WatchProtocol.this)); pipeline.addLast(new WatchProtocolDecoder(WatchProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index cb6ea5319..204bdd341 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -15,17 +15,16 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - import java.nio.charset.StandardCharsets; public class WialonProtocol extends BaseProtocol { @@ -38,9 +37,9 @@ public class WialonProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - boolean utf8 = Context.getConfig().getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); + boolean utf8 = config.getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); if (utf8) { pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); @@ -54,9 +53,9 @@ public class WialonProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - boolean utf8 = Context.getConfig().getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); + boolean utf8 = config.getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); if (utf8) { pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); diff --git a/src/main/java/org/traccar/protocol/WliProtocol.java b/src/main/java/org/traccar/protocol/WliProtocol.java index c10ebf505..aab25abca 100644 --- a/src/main/java/org/traccar/protocol/WliProtocol.java +++ b/src/main/java/org/traccar/protocol/WliProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class WliProtocol extends BaseProtocol { public WliProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WliFrameDecoder()); pipeline.addLast(new WliProtocolDecoder(WliProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java index 6401fde85..dc3ed3413 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocol.java +++ b/src/main/java/org/traccar/protocol/WondexProtocol.java @@ -15,13 +15,13 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringEncoder; - public class WondexProtocol extends BaseProtocol { public WondexProtocol() { @@ -42,7 +42,7 @@ public class WondexProtocol extends BaseProtocol { Command.TYPE_IDENTIFICATION); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WondexFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); @@ -51,7 +51,7 @@ public class WondexProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/WristbandProtocol.java b/src/main/java/org/traccar/protocol/WristbandProtocol.java index 1e5ef2c01..38f85f45a 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocol.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class WristbandProtocol extends BaseProtocol { public WristbandProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, 3, 0)); pipeline.addLast(new WristbandProtocolDecoder(WristbandProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 265841c77..d64190ad8 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Xexun2Protocol extends BaseProtocol { public Xexun2Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java index b83c4e445..2e6d4393b 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocol.java +++ b/src/main/java/org/traccar/protocol/XexunProtocol.java @@ -15,17 +15,16 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - public class XexunProtocol extends BaseProtocol { public XexunProtocol() { @@ -34,8 +33,8 @@ public class XexunProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - boolean full = Context.getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + boolean full = config.getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); if (full) { pipeline.addLast(new LineBasedFrameDecoder(1024)); // tracker bug \n\r } else { diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java index 1be5b6c4b..f986ca3e6 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocol.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java @@ -15,15 +15,15 @@ */ 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 org.traccar.model.Command; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - public class XirgoProtocol extends BaseProtocol { public XirgoProtocol() { @@ -31,7 +31,7 @@ public class XirgoProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -41,7 +41,7 @@ public class XirgoProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new XirgoProtocolEncoder(XirgoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java index 5d8af418b..53eed5595 100644 --- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java +++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.charset.StandardCharsets; @@ -36,7 +37,7 @@ public class Xrb28Protocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder(StandardCharsets.ISO_8859_1)); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Xt013Protocol.java b/src/main/java/org/traccar/protocol/Xt013Protocol.java index ebb3c123f..aaed47c89 100644 --- a/src/main/java/org/traccar/protocol/Xt013Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt013Protocol.java @@ -15,20 +15,20 @@ */ package org.traccar.protocol; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Xt013Protocol extends BaseProtocol { public Xt013Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Xt2400Protocol.java b/src/main/java/org/traccar/protocol/Xt2400Protocol.java index 9427876c8..81567b82c 100644 --- a/src/main/java/org/traccar/protocol/Xt2400Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt2400Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Xt2400Protocol extends BaseProtocol { public Xt2400Protocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xt2400ProtocolDecoder(Xt2400Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/YwtProtocol.java b/src/main/java/org/traccar/protocol/YwtProtocol.java index c525b75cf..6dd8623c9 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocol.java +++ b/src/main/java/org/traccar/protocol/YwtProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class YwtProtocol extends BaseProtocol { public YwtProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 35374a363..2eedd4bd8 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,5 +1,7 @@ package org.traccar; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.traccar.config.Config; import org.traccar.database.ConnectionManager; import org.traccar.database.IdentityManager; @@ -7,7 +9,12 @@ import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.model.Device; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class BaseTest { @@ -20,7 +27,14 @@ public class BaseTest { var device = mock(Device.class); when(device.getId()).thenReturn(1L); var identityManager = mock(IdentityManager.class); + when(identityManager.getById(anyLong())).thenReturn(device); when(identityManager.getByUniqueId(any())).thenReturn(device); + when(identityManager.lookupAttributeBoolean(anyLong(), any(), anyBoolean(), anyBoolean(), anyBoolean())) + .thenAnswer(invocation -> invocation.getArguments()[2]); + when(identityManager.lookupAttributeString(anyLong(), any(), any(), anyBoolean(), anyBoolean())) + .thenAnswer(invocation -> invocation.getArguments()[2]); + when(identityManager.lookupAttributeInteger(anyLong(), any(), anyInt(), anyBoolean(), anyBoolean())) + .thenAnswer(invocation -> invocation.getArguments()[2]); decoder.setIdentityManager(identityManager); decoder.setConnectionManager(mock(ConnectionManager.class)); decoder.setStatisticsManager(mock(StatisticsManager.class)); @@ -33,6 +47,15 @@ public class BaseTest { } protected T inject(T encoder) throws Exception { + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + when(device.getUniqueId()).thenReturn("123456789012345"); + var identityManager = mock(IdentityManager.class); + when(identityManager.getDevicePassword(anyLong(), any(), any())) + .thenAnswer(invocation -> invocation.getArguments()[2]); + when(identityManager.getById(anyLong())).thenReturn(device); + when(identityManager.getByUniqueId(any())).thenReturn(device); + encoder.setIdentityManager(identityManager); return encoder; } diff --git a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java index 89ddef849..79f37c4e4 100644 --- a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java @@ -27,7 +27,7 @@ public class AdmProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new AdmProtocolEncoder(null); + var encoder = inject(new AdmProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java index c72012e5a..bfaa3ccd8 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class BceProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new BceProtocolEncoder(null); + var encoder = inject(new BceProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java index cdf6a7c3b..9b3a285da 100644 --- a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class CastelProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new CastelProtocolEncoder(null); + var encoder = inject(new CastelProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java index 9d42bd65d..bb5d4979d 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class CellocatorProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new CellocatorProtocolEncoder(null); + var encoder = inject(new CellocatorProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java index 2722f6474..6da9856c8 100644 --- a/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class CityeasyProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new CityeasyProtocolEncoder(null); + var encoder = inject(new CityeasyProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java index 79b4e66e3..1e1934435 100644 --- a/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class EasyTrackProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new EasyTrackProtocolEncoder(null); + var encoder = inject(new EasyTrackProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java index 616ca0b52..380888843 100644 --- a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java @@ -7,15 +7,28 @@ import org.traccar.model.Command; public class EelinkProtocolEncoderTest extends ProtocolTest { @Test - public void testEncode() throws Exception { + public void testEncodeTcp() throws Exception { + + var encoder = inject(new EelinkProtocolEncoder(null, false)); Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); - verifyCommand(new EelinkProtocolEncoder(null, false), command, binary("676780000f0000010000000052454c41592c3123")); + verifyCommand(encoder, command, binary("676780000f0000010000000052454c41592c3123")); + + } + + @Test + public void testEncodeUdp() throws Exception { + + var encoder = inject(new EelinkProtocolEncoder(null, true)); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_ENGINE_STOP); - verifyCommand(new EelinkProtocolEncoder(null, true), command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123")); + verifyCommand(encoder, command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123")); } diff --git a/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java index 88be3ebc9..3ea8de5d6 100644 --- a/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class EsealProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new EsealProtocolEncoder(null); + var encoder = inject(new EsealProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java index 2da7f0842..c3352f510 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class FifotrackProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new FifotrackProtocolEncoder(null); + var encoder = inject(new FifotrackProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java index b25100c48..29fe4cc94 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class GalileoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new GalileoProtocolEncoder(null); + var encoder = inject(new GalileoProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java index ae4b52167..9001c4bf3 100644 --- a/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class GlobalSatProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeAlarmDismiss() { + public void testEncodeAlarmDismiss() throws Exception { - var encoder = new GlobalSatProtocolEncoder(null); + var encoder = inject(new GlobalSatProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -22,9 +22,9 @@ public class GlobalSatProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeOutputControl() { + public void testEncodeOutputControl() throws Exception { - var encoder = new GlobalSatProtocolEncoder(null); + var encoder = inject(new GlobalSatProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java index 5edfbf629..f6cbe6d17 100644 --- a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() throws Exception { - var encoder = new Gps103ProtocolEncoder(null); + var encoder = inject(new Gps103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -25,7 +25,7 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - var encoder = new Gps103ProtocolEncoder(null); + var encoder = inject(new Gps103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java index 79165d9dc..13463ea39 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class Gt06ProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new Gt06ProtocolEncoder(null); + var encoder = inject(new Gt06ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java index 3ed0a7e91..1be9421bb 100644 --- a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java @@ -1,5 +1,6 @@ package org.traccar.protocol; +import org.junit.Before; import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; @@ -14,10 +15,15 @@ import static org.junit.Assert.assertEquals; public class H02ProtocolEncoderTest extends ProtocolTest { - private H02ProtocolEncoder encoder = new H02ProtocolEncoder(null); - private Date time = Date.from( + private H02ProtocolEncoder encoder; + private final Date time = Date.from( LocalDateTime.of(LocalDate.now(), LocalTime.of(1, 2, 3)).atZone(ZoneOffset.systemDefault()).toInstant()); + @Before + public void before() throws Exception { + encoder = inject(new H02ProtocolEncoder(null)); + } + @Test public void testAlarmArmEncode() { diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java index 1cb273c2b..6f9c8250a 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class HuabaoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new HuabaoProtocolEncoder(null); + var encoder = inject(new HuabaoProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java index 5302709fc..195fc4258 100644 --- a/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class ItsProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new ItsProtocolEncoder(null); + var encoder = inject(new ItsProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java index 287d05fca..468083f35 100644 --- a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class KhdProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new KhdProtocolEncoder(null); + var encoder = inject(new KhdProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java index 9c50d972a..5b72f6f1f 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new MeiligaoProtocolEncoder(null); + var encoder = inject(new MeiligaoProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java index 64fc7e17b..cc8847db2 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class MeitrackProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new MeitrackProtocolEncoder(null); + var encoder = inject(new MeitrackProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java index 652490b72..502f8e8bf 100644 --- a/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class MiniFinderProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new MiniFinderProtocolEncoder(null); + var encoder = inject(new MiniFinderProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java index 76486d024..d1b28525c 100644 --- a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class NoranProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new NoranProtocolEncoder(null); + var encoder = inject(new NoranProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java index 61f6c4a4e..b4c334a0c 100644 --- a/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class PortmanProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new PortmanProtocolEncoder(null); + var encoder = inject(new PortmanProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -22,9 +22,9 @@ public class PortmanProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeEngineResume() { + public void testEncodeEngineResume() throws Exception { - var encoder = new PortmanProtocolEncoder(null); + var encoder = inject(new PortmanProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java index 403c89e9e..d3218d4a8 100644 --- a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class PretraceProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() throws Exception { - var encoder = new PretraceProtocolEncoder(null); + var encoder = inject(new PretraceProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -25,7 +25,7 @@ public class PretraceProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - var encoder = new PretraceProtocolEncoder(null); + var encoder = inject(new PretraceProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java index abcfa29ec..6c3ff71b6 100644 --- a/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java @@ -7,9 +7,9 @@ import org.traccar.model.Command; public class PstProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new PstProtocolEncoder(null); + var encoder = inject(new PstProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -20,9 +20,9 @@ public class PstProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeEngineResume() { + public void testEncodeEngineResume() throws Exception { - var encoder = new PstProtocolEncoder(null); + var encoder = inject(new PstProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java index 62b83c61c..c97093e26 100644 --- a/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(new Pt502ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -25,7 +25,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeOutputControl() throws Exception { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(new Pt502ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -40,7 +40,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeTimezone() throws Exception { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(new Pt502ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -55,7 +55,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeAlarmSpeed() throws Exception { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(new Pt502ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java index 409cd4da5..0c4fc6767 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class RuptelaProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new RuptelaProtocolEncoder(null); + var encoder = inject(new RuptelaProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java index 7eeb19edf..f04d0cb67 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class StartekProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new StartekProtocolEncoder(null); + var encoder = inject(new StartekProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java index 1d17ee5d5..b2d7c57a2 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class T800xProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new T800xProtocolEncoder(null); + var encoder = inject(new T800xProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java index 008a2b9dd..d7e1149aa 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class TeltonikaProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new TeltonikaProtocolEncoder(null); + var encoder = inject(new TeltonikaProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java index d507f3c4f..359e432c7 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeOutputControl() { + public void testEncodeOutputControl() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -23,9 +23,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -36,9 +36,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionSingle() { + public void testEncodePositionSingle() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -49,9 +49,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionPeriodic() { + public void testEncodePositionPeriodic() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -63,9 +63,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionStop() { + public void testEncodePositionStop() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -76,9 +76,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeGetVersion() { + public void testEncodeGetVersion() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -89,9 +89,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeRebootDevice() { + public void testEncodeRebootDevice() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -102,9 +102,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSetOdometer() { + public void testEncodeSetOdometer() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -115,9 +115,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionSingleAlternative() { + public void testEncodePositionSingleAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -128,9 +128,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionPeriodicAlternative() { + public void testEncodePositionPeriodicAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -141,9 +141,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionStopAlternative() { + public void testEncodePositionStopAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -154,9 +154,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeGetVersionAlternative() { + public void testEncodeGetVersionAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -167,9 +167,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeRebootDeviceAlternative() { + public void testEncodeRebootDeviceAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -180,9 +180,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeIdentificationAlternative() { + public void testEncodeIdentificationAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -193,9 +193,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSosOnAlternative() { + public void testEncodeSosOnAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -207,9 +207,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSosOffAlternative() { + public void testEncodeSosOffAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -221,9 +221,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeCustom() { + public void testEncodeCustom() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -235,9 +235,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeCustomAlternative() { + public void testEncodeCustomAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -249,9 +249,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSetConnectionAlternative() { + public void testEncodeSetConnectionAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -264,9 +264,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSosNumberAlternative() { + public void testEncodeSosNumberAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java index d3ff13941..a69f389ac 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class TopinProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new TopinProtocolEncoder(null); + var encoder = inject(new TopinProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java index a4fca2d9e..97a044b51 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class TotemProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new TotemProtocolEncoder(null); + var encoder = inject(new TotemProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(2); @@ -25,7 +25,7 @@ public class TotemProtocolEncoderTest extends ProtocolTest { @Test public void testSmsEncode() throws Exception { - var encoder = new TotemProtocolSmsEncoder(null); + var encoder = inject(new TotemProtocolSmsEncoder(null)); Command command = new Command(); command.setDeviceId(2); diff --git a/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java index 288f8dc70..50e9321ce 100644 --- a/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java @@ -7,9 +7,9 @@ import org.traccar.model.Command; public class UlbotechProtocolEncoderTest extends ProtocolTest { @Test - public void testEncode() { + public void testEncode() throws Exception { - var encoder = new UlbotechProtocolEncoder(null); + var encoder = inject(new UlbotechProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java index bcfc8df41..c83c103c3 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class WatchProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new WatchProtocolEncoder(null); + var encoder = inject(new WatchProtocolEncoder(null)); Command command; @@ -58,9 +58,9 @@ public class WatchProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeTimezone() { + public void testEncodeTimezone() throws Exception { - var encoder = new WatchProtocolEncoder(null); + var encoder = inject(new WatchProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java index ed0af844e..f482871dd 100644 --- a/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java @@ -10,7 +10,7 @@ public class WondexProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new WondexProtocolEncoder(null); + var encoder = inject(new WondexProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(2); diff --git a/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java index 4f01aa72b..76e2f960d 100644 --- a/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class XirgoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new XirgoProtocolEncoder(null); + var encoder = inject(new XirgoProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java index 357da8f7b..a66efecc2 100644 --- a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class Xrb28ProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodePositionPeriodic() { + public void testEncodePositionPeriodic() throws Exception { - var encoder = new Xrb28ProtocolEncoder(null); + var encoder = inject(new Xrb28ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -23,9 +23,9 @@ public class Xrb28ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeCustom() { + public void testEncodeCustom() throws Exception { - var encoder = new Xrb28ProtocolEncoder(null); + var encoder = inject(new Xrb28ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); -- cgit v1.2.3 From 85f04c6d30e11d8b748ea2b431dbeffce1126a65 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 14:59:09 -0700 Subject: Remove test identity manager --- src/main/java/org/traccar/reports/ReportUtils.java | 27 ++++---- src/test/java/org/traccar/BaseTest.java | 6 -- src/test/java/org/traccar/TestIdentityManager.java | 77 ---------------------- src/test/java/org/traccar/WebDataHandlerTest.java | 15 ++++- .../handler/events/AlertEventHandlerTest.java | 6 +- .../handler/events/IgnitionEventHandlerTest.java | 5 +- .../java/org/traccar/reports/ReportUtilsTest.java | 40 +++++++---- 7 files changed, 62 insertions(+), 114 deletions(-) delete mode 100644 src/test/java/org/traccar/TestIdentityManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index 23646c4d6..dd1ef478f 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -171,7 +171,8 @@ public final class ReportUtils { } private static TripReport calculateTrip( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { Position startTrip = positions.get(startIndex); Position endTrip = positions.get(endIndex); @@ -189,7 +190,7 @@ public final class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + trip.setDeviceName(identityManager.getById(deviceId).getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -238,7 +239,8 @@ public final class ReportUtils { } private static StopReport calculateStop( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -247,7 +249,7 @@ public final class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + stop.setDeviceName(identityManager.getById(deviceId).getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); @@ -286,12 +288,13 @@ public final class ReportUtils { } private static T calculateTripOrStop( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { if (reportClass.equals(TripReport.class)) { - return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); } else { - return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); } } @@ -351,15 +354,15 @@ public final class ReportUtils { } if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(positions, startEventIndex, startNoEventIndex, - ignoreOdometer, reportClass)); + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(positions, startEventIndex, - startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, - ignoreOdometer, reportClass)); + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, + ignoreOdometer, reportClass)); } } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 2eedd4bd8..0f6c55857 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,7 +1,5 @@ package org.traccar; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; import org.traccar.config.Config; import org.traccar.database.ConnectionManager; import org.traccar.database.IdentityManager; @@ -18,10 +16,6 @@ import static org.mockito.Mockito.when; public class BaseTest { - static { - Context.init(new TestIdentityManager()); - } - protected T inject(T decoder) throws Exception { decoder.setConfig(new Config()); var device = mock(Device.class); diff --git a/src/test/java/org/traccar/TestIdentityManager.java b/src/test/java/org/traccar/TestIdentityManager.java deleted file mode 100644 index 68d98db9a..000000000 --- a/src/test/java/org/traccar/TestIdentityManager.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.traccar; - -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Position; - -public final class TestIdentityManager implements IdentityManager { - - private static Device createDevice() { - Device device = new Device(); - device.setId(1); - device.setName("test"); - device.setUniqueId("123456789012345"); - return device; - } - - @Override - public long addUnknownDevice(String uniqueId) { - return 1; - } - - @Override - public Device getById(long id) { - return createDevice(); - } - - @Override - public Device getByUniqueId(String uniqueId) { - return createDevice(); - } - - @Override - public String getDevicePassword(long id, String protocol, String defaultPassword) { - return defaultPassword; - } - - @Override - public Position getLastPosition(long deviceId) { - return null; - } - - @Override - public boolean isLatestPosition(Position position) { - return true; - } - - @Override - public boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public int lookupAttributeInteger( - long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - -} diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index cfbd71f23..aaec9f530 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -3,9 +3,14 @@ package org.traccar; import org.junit.Test; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; import org.traccar.model.Position; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class WebDataHandlerTest extends ProtocolTest { @@ -17,7 +22,15 @@ public class WebDataHandlerTest extends ProtocolTest { Position position = position("2016-01-01 01:02:03.000", true, 20, 30); - WebDataHandler handler = new WebDataHandler(config, Context.getIdentityManager(), null, null); + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + when(device.getName()).thenReturn("test"); + when(device.getUniqueId()).thenReturn("123456789012345"); + when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); + var identityManager = mock(IdentityManager.class); + when(identityManager.getById(anyLong())).thenReturn(device); + + WebDataHandler handler = new WebDataHandler(config, identityManager, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", diff --git a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java index 3f0823245..4934695ad 100644 --- a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java @@ -2,13 +2,14 @@ package org.traccar.handler.events; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; import java.util.Map; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.TestIdentityManager; import org.traccar.config.Config; +import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; @@ -17,7 +18,7 @@ public class AlertEventHandlerTest extends BaseTest { @Test public void testAlertEventHandler() { - AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), new TestIdentityManager()); + AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), mock(IdentityManager.class)); Position position = new Position(); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); @@ -25,6 +26,7 @@ public class AlertEventHandlerTest extends BaseTest { assertNotNull(events); Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_ALARM, event.getType()); + } } diff --git a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java index dade20fb8..f568b6a74 100644 --- a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java @@ -1,12 +1,13 @@ package org.traccar.handler.events; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; import java.util.Map; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.TestIdentityManager; +import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; @@ -15,7 +16,7 @@ public class IgnitionEventHandlerTest extends BaseTest { @Test public void testIgnitionEventHandler() { - IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(new TestIdentityManager()); + IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(mock(IdentityManager.class)); Position position = new Position(); position.set(Position.KEY_IGNITION, true); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index deb17ddd2..b27104f76 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -4,6 +4,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.text.DateFormat; import java.text.ParseException; @@ -17,7 +20,8 @@ import java.util.TimeZone; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.TestIdentityManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; @@ -43,6 +47,14 @@ public class ReportUtilsTest extends BaseTest { return position; } + private IdentityManager mockIdentityManager() { + var device = mock(Device.class); + when(device.getName()).thenReturn("test"); + var identityManager = mock(IdentityManager.class); + when(identityManager.getById(anyLong())).thenReturn(device); + return identityManager; + } + @Test public void testCalculateDistance() { Position startPosition = new Position(); @@ -81,7 +93,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -96,7 +108,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -135,7 +147,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -150,7 +162,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -165,7 +177,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -206,7 +218,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -221,7 +233,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -256,7 +268,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -283,7 +295,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -310,7 +322,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -337,7 +349,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -360,7 +372,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -375,7 +387,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(600, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 00b91d01d89a32710baa9e580bdf581dae7aa711 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 16:44:20 -0700 Subject: Combine session related classes --- src/main/java/org/traccar/BaseProtocolDecoder.java | 3 +- src/main/java/org/traccar/Context.java | 2 +- src/main/java/org/traccar/DeviceSession.java | 42 ---- src/main/java/org/traccar/MainModule.java | 2 +- src/main/java/org/traccar/api/AsyncSocket.java | 2 +- .../java/org/traccar/database/ActiveDevice.java | 58 ------ .../java/org/traccar/database/CommandsManager.java | 1 + .../org/traccar/database/ConnectionManager.java | 219 --------------------- .../java/org/traccar/database/DeviceManager.java | 2 +- .../handler/events/GeofenceEventHandler.java | 2 +- .../traccar/handler/events/MotionEventHandler.java | 2 +- .../handler/events/OverspeedEventHandler.java | 2 +- src/main/java/org/traccar/model/DeviceState.java | 71 ------- .../org/traccar/protocol/AdmProtocolDecoder.java | 2 +- .../org/traccar/protocol/AisProtocolDecoder.java | 2 +- .../traccar/protocol/AlematicsProtocolDecoder.java | 2 +- .../traccar/protocol/AnytrekProtocolDecoder.java | 2 +- .../org/traccar/protocol/ApelProtocolDecoder.java | 2 +- .../traccar/protocol/AplicomProtocolDecoder.java | 2 +- .../traccar/protocol/AppelloProtocolDecoder.java | 2 +- .../traccar/protocol/AquilaProtocolDecoder.java | 2 +- .../traccar/protocol/Ardi01ProtocolDecoder.java | 2 +- .../traccar/protocol/ArknavProtocolDecoder.java | 2 +- .../traccar/protocol/ArknavX8ProtocolDecoder.java | 2 +- .../traccar/protocol/ArmoliProtocolDecoder.java | 2 +- .../protocol/ArnaviBinaryProtocolDecoder.java | 2 +- .../protocol/ArnaviTextProtocolDecoder.java | 2 +- .../org/traccar/protocol/AstraProtocolDecoder.java | 2 +- .../traccar/protocol/At2000ProtocolDecoder.java | 2 +- .../traccar/protocol/AtrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/AuroProtocolDecoder.java | 2 +- .../traccar/protocol/AustinNbProtocolDecoder.java | 2 +- .../traccar/protocol/AutoFonProtocolDecoder.java | 2 +- .../traccar/protocol/AutoGradeProtocolDecoder.java | 2 +- .../traccar/protocol/AutoTrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/AvemaProtocolDecoder.java | 2 +- .../traccar/protocol/Avl301ProtocolDecoder.java | 2 +- .../org/traccar/protocol/B2316ProtocolDecoder.java | 2 +- .../org/traccar/protocol/BceProtocolDecoder.java | 2 +- .../traccar/protocol/BlackKiteProtocolDecoder.java | 2 +- .../org/traccar/protocol/BlueProtocolDecoder.java | 2 +- .../org/traccar/protocol/BoxProtocolDecoder.java | 2 +- .../traccar/protocol/C2stekProtocolDecoder.java | 2 +- .../traccar/protocol/CalAmpProtocolDecoder.java | 2 +- .../traccar/protocol/CarTrackProtocolDecoder.java | 2 +- .../traccar/protocol/CarcellProtocolDecoder.java | 2 +- .../traccar/protocol/CarscopProtocolDecoder.java | 2 +- .../traccar/protocol/CastelProtocolDecoder.java | 2 +- .../traccar/protocol/CautelaProtocolDecoder.java | 2 +- .../protocol/CellocatorProtocolDecoder.java | 2 +- .../traccar/protocol/CguardProtocolDecoder.java | 2 +- .../traccar/protocol/CityeasyProtocolDecoder.java | 2 +- .../protocol/ContinentalProtocolDecoder.java | 2 +- .../protocol/CradlepointProtocolDecoder.java | 2 +- .../traccar/protocol/DingtekProtocolDecoder.java | 2 +- .../org/traccar/protocol/DishaProtocolDecoder.java | 2 +- .../traccar/protocol/DmtHttpProtocolDecoder.java | 2 +- .../org/traccar/protocol/DmtProtocolDecoder.java | 2 +- .../traccar/protocol/DolphinProtocolDecoder.java | 2 +- .../org/traccar/protocol/Dsf22ProtocolDecoder.java | 2 +- .../traccar/protocol/DualcamProtocolDecoder.java | 2 +- .../org/traccar/protocol/DwayProtocolDecoder.java | 2 +- .../traccar/protocol/EasyTrackProtocolDecoder.java | 2 +- .../traccar/protocol/EelinkProtocolDecoder.java | 2 +- .../org/traccar/protocol/EgtsProtocolDecoder.java | 2 +- .../traccar/protocol/EnforaProtocolDecoder.java | 2 +- .../org/traccar/protocol/EnnfuProtocolDecoder.java | 2 +- .../traccar/protocol/EnvotechProtocolDecoder.java | 2 +- .../org/traccar/protocol/EsealProtocolDecoder.java | 2 +- .../org/traccar/protocol/EskyProtocolDecoder.java | 2 +- .../protocol/ExtremTracProtocolDecoder.java | 2 +- .../traccar/protocol/FifotrackProtocolDecoder.java | 2 +- .../traccar/protocol/FlespiProtocolDecoder.java | 2 +- .../traccar/protocol/FlexApiProtocolDecoder.java | 2 +- .../traccar/protocol/FlexCommProtocolDecoder.java | 2 +- .../protocol/FlexibleReportProtocolDecoder.java | 2 +- .../traccar/protocol/FlextrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/FoxProtocolDecoder.java | 2 +- .../traccar/protocol/FreedomProtocolDecoder.java | 2 +- .../protocol/FreematicsProtocolDecoder.java | 2 +- .../traccar/protocol/FutureWayProtocolDecoder.java | 2 +- .../traccar/protocol/GalileoProtocolDecoder.java | 2 +- .../org/traccar/protocol/GatorProtocolDecoder.java | 2 +- .../org/traccar/protocol/GenxProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gl100ProtocolDecoder.java | 2 +- .../protocol/Gl200BinaryProtocolDecoder.java | 2 +- .../traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- .../traccar/protocol/GlobalSatProtocolDecoder.java | 2 +- .../protocol/GlobalstarProtocolDecoder.java | 2 +- .../org/traccar/protocol/GnxProtocolDecoder.java | 2 +- .../traccar/protocol/GoSafeProtocolDecoder.java | 2 +- .../org/traccar/protocol/GotopProtocolDecoder.java | 2 +- .../traccar/protocol/Gps056ProtocolDecoder.java | 2 +- .../traccar/protocol/Gps103ProtocolDecoder.java | 2 +- .../traccar/protocol/GpsGateProtocolDecoder.java | 2 +- .../traccar/protocol/GpsMarkerProtocolDecoder.java | 2 +- .../traccar/protocol/GpsmtaProtocolDecoder.java | 2 +- .../traccar/protocol/GranitProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gs100ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt02ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt30ProtocolDecoder.java | 2 +- .../org/traccar/protocol/H02ProtocolDecoder.java | 2 +- .../traccar/protocol/HaicomProtocolDecoder.java | 2 +- .../traccar/protocol/HomtecsProtocolDecoder.java | 2 +- .../org/traccar/protocol/HoopoProtocolDecoder.java | 2 +- .../traccar/protocol/HuaShengProtocolDecoder.java | 2 +- .../traccar/protocol/HuabaoProtocolDecoder.java | 2 +- .../traccar/protocol/HunterProProtocolDecoder.java | 2 +- .../org/traccar/protocol/IdplProtocolDecoder.java | 2 +- .../protocol/IntellitracProtocolDecoder.java | 2 +- .../org/traccar/protocol/IotmProtocolDecoder.java | 2 +- .../org/traccar/protocol/ItsProtocolDecoder.java | 2 +- .../traccar/protocol/Ivt401ProtocolDecoder.java | 2 +- .../org/traccar/protocol/JidoProtocolDecoder.java | 2 +- .../traccar/protocol/JpKorjarProtocolDecoder.java | 2 +- .../org/traccar/protocol/Jt600ProtocolDecoder.java | 2 +- .../org/traccar/protocol/KenjiProtocolDecoder.java | 2 +- .../org/traccar/protocol/KhdProtocolDecoder.java | 2 +- .../org/traccar/protocol/L100ProtocolDecoder.java | 2 +- .../org/traccar/protocol/LacakProtocolDecoder.java | 2 +- .../traccar/protocol/LaipacProtocolDecoder.java | 2 +- .../traccar/protocol/LeafSpyProtocolDecoder.java | 2 +- .../org/traccar/protocol/M2cProtocolDecoder.java | 2 +- .../org/traccar/protocol/M2mProtocolDecoder.java | 2 +- .../traccar/protocol/MaestroProtocolDecoder.java | 2 +- .../traccar/protocol/ManPowerProtocolDecoder.java | 2 +- .../traccar/protocol/Mavlink2ProtocolDecoder.java | 2 +- .../traccar/protocol/MegastekProtocolDecoder.java | 2 +- .../traccar/protocol/MeiligaoProtocolDecoder.java | 2 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 2 +- .../traccar/protocol/MictrackProtocolDecoder.java | 2 +- .../traccar/protocol/MilesmateProtocolDecoder.java | 2 +- .../protocol/MiniFinderProtocolDecoder.java | 2 +- .../protocol/Minifinder2ProtocolDecoder.java | 2 +- .../traccar/protocol/MobilogixProtocolDecoder.java | 2 +- .../traccar/protocol/MoovboxProtocolDecoder.java | 2 +- .../org/traccar/protocol/MotorProtocolDecoder.java | 2 +- .../org/traccar/protocol/Mta6ProtocolDecoder.java | 2 +- .../org/traccar/protocol/MtxProtocolDecoder.java | 2 +- .../org/traccar/protocol/MxtProtocolDecoder.java | 2 +- .../traccar/protocol/NavigilProtocolDecoder.java | 2 +- .../org/traccar/protocol/NavisProtocolDecoder.java | 2 +- .../traccar/protocol/NavisetProtocolDecoder.java | 2 +- .../protocol/NavtelecomProtocolDecoder.java | 2 +- .../org/traccar/protocol/NeosProtocolDecoder.java | 2 +- .../org/traccar/protocol/NetProtocolDecoder.java | 2 +- .../org/traccar/protocol/NiotProtocolDecoder.java | 2 +- .../org/traccar/protocol/NoranProtocolDecoder.java | 2 +- .../org/traccar/protocol/NvsProtocolDecoder.java | 2 +- .../traccar/protocol/NyitechProtocolDecoder.java | 2 +- .../traccar/protocol/ObdDongleProtocolDecoder.java | 2 +- .../org/traccar/protocol/OigoProtocolDecoder.java | 2 +- .../org/traccar/protocol/OkoProtocolDecoder.java | 2 +- .../traccar/protocol/OmnicommProtocolDecoder.java | 2 +- .../traccar/protocol/OpenGtsProtocolDecoder.java | 2 +- .../traccar/protocol/OrbcommProtocolDecoder.java | 2 +- .../org/traccar/protocol/OrionProtocolDecoder.java | 2 +- .../traccar/protocol/OsmAndProtocolDecoder.java | 2 +- .../traccar/protocol/OutsafeProtocolDecoder.java | 2 +- .../traccar/protocol/OwnTracksProtocolDecoder.java | 2 +- .../protocol/PacificTrackProtocolDecoder.java | 2 +- .../traccar/protocol/PathAwayProtocolDecoder.java | 2 +- .../traccar/protocol/PiligrimProtocolDecoder.java | 2 +- .../traccar/protocol/PluginProtocolDecoder.java | 2 +- .../org/traccar/protocol/PolteProtocolDecoder.java | 2 +- .../traccar/protocol/PortmanProtocolDecoder.java | 2 +- .../traccar/protocol/PretraceProtocolDecoder.java | 2 +- .../traccar/protocol/PricolProtocolDecoder.java | 2 +- .../traccar/protocol/ProgressProtocolDecoder.java | 2 +- .../org/traccar/protocol/PstProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt215ProtocolDecoder.java | 2 +- .../traccar/protocol/Pt3000ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt60ProtocolDecoder.java | 2 +- .../org/traccar/protocol/R12wProtocolDecoder.java | 2 +- .../protocol/RaceDynamicsProtocolDecoder.java | 2 +- .../org/traccar/protocol/RadarProtocolDecoder.java | 2 +- .../traccar/protocol/RaveonProtocolDecoder.java | 2 +- .../traccar/protocol/RecodaProtocolDecoder.java | 2 +- .../protocol/RetranslatorProtocolDecoder.java | 2 +- .../org/traccar/protocol/RitiProtocolDecoder.java | 2 +- .../traccar/protocol/RoboTrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/RstProtocolDecoder.java | 2 +- .../traccar/protocol/RuptelaProtocolDecoder.java | 2 +- .../org/traccar/protocol/S168ProtocolDecoder.java | 2 +- .../traccar/protocol/SabertekProtocolDecoder.java | 2 +- .../org/traccar/protocol/SanavProtocolDecoder.java | 2 +- .../org/traccar/protocol/SanulProtocolDecoder.java | 2 +- .../traccar/protocol/SatsolProtocolDecoder.java | 2 +- .../traccar/protocol/SigfoxProtocolDecoder.java | 2 +- .../org/traccar/protocol/SiwiProtocolDecoder.java | 2 +- .../traccar/protocol/SkypatrolProtocolDecoder.java | 2 +- .../traccar/protocol/SmartSoleProtocolDecoder.java | 2 +- .../traccar/protocol/SmokeyProtocolDecoder.java | 2 +- .../protocol/SolarPoweredProtocolDecoder.java | 2 +- .../org/traccar/protocol/SpotProtocolDecoder.java | 2 +- .../traccar/protocol/StarLinkProtocolDecoder.java | 2 +- .../traccar/protocol/StarcomProtocolDecoder.java | 2 +- .../traccar/protocol/StartekProtocolDecoder.java | 2 +- .../org/traccar/protocol/StbProtocolDecoder.java | 2 +- .../traccar/protocol/Stl060ProtocolDecoder.java | 2 +- .../traccar/protocol/SuntechProtocolDecoder.java | 2 +- .../traccar/protocol/SupermateProtocolDecoder.java | 2 +- .../org/traccar/protocol/SviasProtocolDecoder.java | 2 +- .../traccar/protocol/SwiftechProtocolDecoder.java | 2 +- .../org/traccar/protocol/T55ProtocolDecoder.java | 2 +- .../org/traccar/protocol/T57ProtocolDecoder.java | 2 +- .../org/traccar/protocol/T800xProtocolDecoder.java | 2 +- .../org/traccar/protocol/TaipProtocolDecoder.java | 2 +- .../traccar/protocol/TechTltProtocolDecoder.java | 2 +- .../protocol/TechtoCruzProtocolDecoder.java | 2 +- .../org/traccar/protocol/TekProtocolDecoder.java | 2 +- .../traccar/protocol/TelemaxProtocolDecoder.java | 2 +- .../org/traccar/protocol/TelicProtocolDecoder.java | 2 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- .../traccar/protocol/TeraTrackProtocolDecoder.java | 2 +- .../protocol/ThinkPowerProtocolDecoder.java | 2 +- .../traccar/protocol/ThinkRaceProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tk102ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tlt2hProtocolDecoder.java | 2 +- .../org/traccar/protocol/TlvProtocolDecoder.java | 2 +- .../org/traccar/protocol/TmgProtocolDecoder.java | 2 +- .../protocol/TopflytechProtocolDecoder.java | 2 +- .../org/traccar/protocol/TopinProtocolDecoder.java | 2 +- .../org/traccar/protocol/TotemProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tr20ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tr900ProtocolDecoder.java | 2 +- .../traccar/protocol/TrackboxProtocolDecoder.java | 2 +- .../traccar/protocol/TrakMateProtocolDecoder.java | 2 +- .../traccar/protocol/TramigoProtocolDecoder.java | 2 +- .../org/traccar/protocol/TrvProtocolDecoder.java | 2 +- .../traccar/protocol/Tt8850ProtocolDecoder.java | 2 +- .../org/traccar/protocol/TytanProtocolDecoder.java | 2 +- .../org/traccar/protocol/TzoneProtocolDecoder.java | 2 +- .../traccar/protocol/UlbotechProtocolDecoder.java | 2 +- .../org/traccar/protocol/UproProtocolDecoder.java | 2 +- .../org/traccar/protocol/UuxProtocolDecoder.java | 2 +- .../org/traccar/protocol/V680ProtocolDecoder.java | 2 +- .../traccar/protocol/VisiontekProtocolDecoder.java | 2 +- .../org/traccar/protocol/VnetProtocolDecoder.java | 2 +- .../org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- .../org/traccar/protocol/VtfmsProtocolDecoder.java | 2 +- .../org/traccar/protocol/WatchProtocolDecoder.java | 2 +- .../traccar/protocol/WialonProtocolDecoder.java | 2 +- .../org/traccar/protocol/WliProtocolDecoder.java | 2 +- .../traccar/protocol/WondexProtocolDecoder.java | 2 +- .../traccar/protocol/WristbandProtocolDecoder.java | 2 +- .../traccar/protocol/Xexun2ProtocolDecoder.java | 2 +- .../org/traccar/protocol/XexunProtocolDecoder.java | 2 +- .../org/traccar/protocol/XirgoProtocolDecoder.java | 2 +- .../org/traccar/protocol/Xrb28ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Xt013ProtocolDecoder.java | 2 +- .../traccar/protocol/Xt2400ProtocolDecoder.java | 2 +- .../org/traccar/protocol/YwtProtocolDecoder.java | 2 +- src/main/java/org/traccar/reports/ReportUtils.java | 2 +- .../java/org/traccar/session/ActiveDevice.java | 58 ++++++ .../org/traccar/session/ConnectionManager.java | 218 ++++++++++++++++++++ .../java/org/traccar/session/DeviceSession.java | 42 ++++ src/main/java/org/traccar/session/DeviceState.java | 73 +++++++ src/test/java/org/traccar/BaseTest.java | 2 +- .../handler/events/MotionEventHandlerTest.java | 2 +- .../handler/events/OverspeedEventHandlerTest.java | 2 +- 264 files changed, 648 insertions(+), 645 deletions(-) delete mode 100644 src/main/java/org/traccar/DeviceSession.java delete mode 100644 src/main/java/org/traccar/database/ActiveDevice.java delete mode 100644 src/main/java/org/traccar/database/ConnectionManager.java delete mode 100644 src/main/java/org/traccar/model/DeviceState.java create mode 100644 src/main/java/org/traccar/session/ActiveDevice.java create mode 100644 src/main/java/org/traccar/session/ConnectionManager.java create mode 100644 src/main/java/org/traccar/session/DeviceSession.java create mode 100644 src/main/java/org/traccar/session/DeviceState.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 9a396bd64..3fc6e7697 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; @@ -33,6 +33,7 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import java.net.InetSocketAddress; import java.net.SocketAddress; diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 237a34624..1faa4c9de 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -27,7 +27,7 @@ import org.traccar.database.AttributesManager; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; import org.traccar.database.CommandsManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; diff --git a/src/main/java/org/traccar/DeviceSession.java b/src/main/java/org/traccar/DeviceSession.java deleted file mode 100644 index 322381807..000000000 --- a/src/main/java/org/traccar/DeviceSession.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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; - -import java.util.TimeZone; - -public class DeviceSession { - - private final long deviceId; - - public DeviceSession(long deviceId) { - this.deviceId = deviceId; - } - - public long getDeviceId() { - return deviceId; - } - - private TimeZone timeZone; - - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; - } - - public TimeZone getTimeZone() { - return timeZone; - } - -} diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 60b5854fd..43ca3ba77 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -26,7 +26,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.AttributesManager; import org.traccar.database.CalendarManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index b1853822d..b5902c4fb 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -21,7 +21,7 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/database/ActiveDevice.java b/src/main/java/org/traccar/database/ActiveDevice.java deleted file mode 100644 index c05d56ad2..000000000 --- a/src/main/java/org/traccar/database/ActiveDevice.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 - 2020 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.database; - -import io.netty.channel.Channel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import org.traccar.BasePipelineFactory; -import org.traccar.Protocol; -import org.traccar.model.Command; - -import java.net.SocketAddress; - -public class ActiveDevice { - - private final long deviceId; - private final Protocol protocol; - private final Channel channel; - private final SocketAddress remoteAddress; - private final boolean supportsLiveCommands; - - public ActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - this.deviceId = deviceId; - this.protocol = protocol; - this.channel = channel; - this.remoteAddress = remoteAddress; - supportsLiveCommands = BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; - } - - public Channel getChannel() { - return channel; - } - - public long getDeviceId() { - return deviceId; - } - - public boolean supportsLiveCommands() { - return supportsLiveCommands; - } - - public void sendCommand(Command command) { - protocol.sendDataCommand(channel, remoteAddress, command); - } - -} diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 843c89e82..3adf5d2e9 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -34,6 +34,7 @@ import org.traccar.Context; import org.traccar.model.Command; import org.traccar.model.Typed; import org.traccar.model.Position; +import org.traccar.session.ActiveDevice; public class CommandsManager extends ExtendedObjectManager { diff --git a/src/main/java/org/traccar/database/ConnectionManager.java b/src/main/java/org/traccar/database/ConnectionManager.java deleted file mode 100644 index f0e40f631..000000000 --- a/src/main/java/org/traccar/database/ConnectionManager.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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. - * 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.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.Main; -import org.traccar.Protocol; -import org.traccar.config.Keys; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; -import org.traccar.model.Device; -import org.traccar.model.DeviceState; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.storage.StorageException; - -import java.net.SocketAddress; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; - -public class ConnectionManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); - - private final long deviceTimeout; - private final boolean updateDeviceState; - - private final Map activeDevices = new ConcurrentHashMap<>(); - 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) { - activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); - } - - public void removeActiveDevice(Channel channel) { - for (ActiveDevice activeDevice : activeDevices.values()) { - if (activeDevice.getChannel() == channel) { - updateDevice(activeDevice.getDeviceId(), Device.STATUS_OFFLINE, null); - activeDevices.remove(activeDevice.getDeviceId()); - break; - } - } - } - - public ActiveDevice getActiveDevice(long deviceId) { - return activeDevices.get(deviceId); - } - - public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getById(deviceId); - if (device == null) { - return; - } - - String oldStatus = device.getStatus(); - device.setStatus(status); - - if (!status.equals(oldStatus)) { - String eventType; - Map events = new HashMap<>(); - switch (status) { - case Device.STATUS_ONLINE: - eventType = Event.TYPE_DEVICE_ONLINE; - break; - case Device.STATUS_UNKNOWN: - eventType = Event.TYPE_DEVICE_UNKNOWN; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } - break; - default: - eventType = Event.TYPE_DEVICE_OFFLINE; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } - break; - } - events.put(new Event(eventType, deviceId), null); - Context.getNotificationManager().updateEvents(events); - } - - Timeout timeout = timeouts.remove(deviceId); - if (timeout != null) { - timeout.cancel(); - } - - if (time != null) { - device.setLastUpdate(time); - } - - if (status.equals(Device.STATUS_ONLINE)) { - timeouts.put(deviceId, timer.newTimeout(timeout1 -> { - if (!timeout1.isCancelled()) { - updateDevice(deviceId, Device.STATUS_UNKNOWN, null); - } - }, deviceTimeout, TimeUnit.MILLISECONDS)); - } - - try { - Context.getDeviceManager().updateDeviceStatus(device); - } catch (StorageException e) { - LOGGER.warn("Update device status error", e); - } - - updateDevice(device); - } - - public Map updateDeviceState(long deviceId) { - DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - Map result = new HashMap<>(); - - Map event = Main.getInjector() - .getInstance(MotionEventHandler.class).updateMotionState(deviceState); - if (event != null) { - result.putAll(event); - } - - event = Main.getInjector().getInstance(OverspeedEventHandler.class) - .updateOverspeedState(deviceState, Context.getDeviceManager(). - lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false)); - if (event != null) { - result.putAll(event); - } - - return result; - } - - public synchronized void sendKeepalive() { - for (Set userListeners : listeners.values()) { - for (UpdateListener listener : userListeners) { - listener.onKeepalive(); - } - } - } - - public synchronized void updateDevice(Device device) { - for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdateDevice(device); - } - } - } - } - - public synchronized void updatePosition(Position position) { - long deviceId = position.getDeviceId(); - - for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdatePosition(position); - } - } - } - } - - public synchronized void updateEvent(long userId, Event event) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdateEvent(event); - } - } - } - - public interface UpdateListener { - void onKeepalive(); - void onUpdateDevice(Device device); - void onUpdatePosition(Position position); - void onUpdateEvent(Event event); - } - - public synchronized void addListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); - } - listeners.get(userId).add(listener); - } - - public synchronized void removeListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); - } - listeners.get(userId).remove(listener); - } - -} diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index a14fd7022..3b500aba9 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -31,7 +31,7 @@ import org.traccar.Context; import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 36df7aaf3..c7dcf3f59 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -22,7 +22,7 @@ import java.util.Map; import io.netty.channel.ChannelHandler; import org.traccar.database.CalendarManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Calendar; diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 23a39d070..e27faf9ce 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -23,7 +23,7 @@ import io.netty.channel.ChannelHandler; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.ReportUtils; diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 102003c3c..84d80e55f 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -25,7 +25,7 @@ import org.traccar.config.Keys; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; import org.traccar.model.Device; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/model/DeviceState.java b/src/main/java/org/traccar/model/DeviceState.java deleted file mode 100644 index 75d6726ee..000000000 --- a/src/main/java/org/traccar/model/DeviceState.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.model; - -public class DeviceState { - - private Boolean motionState; - - public void setMotionState(boolean motionState) { - this.motionState = motionState; - } - - public Boolean getMotionState() { - return motionState; - } - - private Position motionPosition; - - public void setMotionPosition(Position motionPosition) { - this.motionPosition = motionPosition; - } - - public Position getMotionPosition() { - return motionPosition; - } - - private Boolean overspeedState; - - public void setOverspeedState(boolean overspeedState) { - this.overspeedState = overspeedState; - } - - public Boolean getOverspeedState() { - return overspeedState; - } - - private Position overspeedPosition; - - public void setOverspeedPosition(Position overspeedPosition) { - this.overspeedPosition = overspeedPosition; - } - - public Position getOverspeedPosition() { - return overspeedPosition; - } - - private long overspeedGeofenceId; - - public void setOverspeedGeofenceId(long overspeedGeofenceId) { - this.overspeedGeofenceId = overspeedGeofenceId; - } - - public long getOverspeedGeofenceId() { - return overspeedGeofenceId; - } - -} diff --git a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java index 7e3478704..1f940f7e2 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/AisProtocolDecoder.java b/src/main/java/org/traccar/protocol/AisProtocolDecoder.java index 8970f3d4a..a434e6e33 100644 --- a/src/main/java/org/traccar/protocol/AisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AisProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitBuffer; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java index 25ccf6856..981437191 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java b/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java index c48f59c90..0f9c2b17a 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java b/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java index c95a0366a..97ed7de96 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java index 692a2058a..0cd8ca37e 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java b/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java index 47e329234..8e182b9fb 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java index 3c43ddf2a..50ff10469 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java index 85e9ecfde..07653623a 100644 --- a/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java index 4982e02fc..4def9c979 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java index b570f5423..22c0344d6 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java index 50af039d6..cbed64f76 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.ObdDecoder; diff --git a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java index e957a6911..0f6b7a33f 100644 --- a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java index b99869e6e..9d82c9ad5 100644 --- a/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java index e6f546b9f..366bf9e8b 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java b/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java index 43798eb67..b81ba306d 100644 --- a/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 9a5d537ef..4567582db 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java b/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java index d7916147b..4489cf27e 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java index dc6f3d280..92dae7285 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java index aa05ca2d7..dd6a0e33c 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java index 5052450b5..f52ac81c9 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java index da7f6b5a6..c072e55d0 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java index 37836ad5f..0793975df 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java index 9f6ded26a..8f036fc29 100644 --- a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java index 854107a20..a45c315b3 100644 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.CellTower; import org.traccar.model.Network; diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index 535827f3c..2c9459584 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java index 474ceabdc..64fc439c4 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java index f35ac6fbe..db59c564d 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java index 853fa8f81..8e92b69fb 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index e735c67a1..42a61ef85 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java index 59b1fdf21..57f9c69ae 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java index ce3345826..3f5418549 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java index ec640ba71..54ae068fb 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java @@ -20,7 +20,7 @@ import java.util.regex.Pattern; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.Parser.CoordinateFormat; diff --git a/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java index 161666adc..f13a1d0eb 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 85ac29336..c2b740c4c 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java index bddf19b41..37f733ac1 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index 09bd3572f..ecd09a2d8 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java index d934921f1..90f8e0caf 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java b/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java index 9c4c7e11d..1b5eb55d4 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java b/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java index 471afa0d6..280871e1e 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java index a282131ce..924603291 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java b/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java index 98fe4b7b3..580741ec9 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java b/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java index 3223988ab..1327e7a6c 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 815cce987..807850778 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java index 96b06557a..0fd83f503 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java index d509b3ec0..b43635a52 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java index 3ef960f12..124bbfefa 100644 --- a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index 3c15d41eb..c5835bc7d 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java b/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java index 9b02c898e..9cf40b011 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java index 4fcc48944..805cf1197 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 592e5a56c..f6b5720da 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java index e65ddb0ef..3a6af60a1 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java index bfa7a116b..dd1c8017b 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BufferUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java index 792ed1098..2198938e2 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 65d5e3859..750ff2bda 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index 27fcf1394..dd15c4276 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java index 14b4376d5..4239022d0 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java b/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java index 9fde6f0a0..706c70825 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 53f35c3cd..741f4b35a 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 281a8a84f..6e6f9c700 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index bcfbdd7da..2dec44e64 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.CellTower; import org.traccar.model.Network; diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java index 068c0a05c..0d8bd9373 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java index 759f2cd6f..9fcee1aeb 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java index 9dce22ede..a0dac1c41 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java index 449f00022..6dd0b0e95 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java index 1d2dd3133..27dda1a6d 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java index aded35823..4e5200f37 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java b/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java index c2f3781d9..57027b080 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 4c6d915d5..a2ba7b029 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java index 087861635..644caee81 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java index b787b7467..6448b6a5a 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java index ae0383e5c..789d87dad 100644 --- a/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index c3339bea5..ecd1f5bfa 100644 --- a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitBuffer; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 72d3ef592..ebd58ed5c 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -16,7 +16,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java index d5c834284..720b61695 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java index b742d0cac..e537edf1d 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java @@ -27,7 +27,7 @@ import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java index c9c221a69..9c8b6879a 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index a86249224..77649a041 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java index 0f8d29228..5c8d0bac2 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java index 0ba79bb51..eea64364e 100644 --- a/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index 510f5eca2..a2009e1b2 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java index c158d3212..82da58f1e 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java index bbb2c31e2..0fef4b7da 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java index 31f9401b4..a9b85d255 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java b/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java index 292e43a0e..dfc3c10f6 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java index 2496aad48..352070107 100644 --- a/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java index 78a3fd3ee..4ecb0b43b 100644 --- a/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 22f38a497..c200c6ba9 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java index abf208a46..fb3a2b8ae 100644 --- a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index dcfb36fd1..2ad4f644b 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java index dd20f2aeb..9903e7735 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java b/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java index a93572b5c..5541cb065 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java index af51a99c6..708c74f2a 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 891046213..371691d82 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 84120028a..c75fd673a 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java b/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java index 06bc12d59..eada1fd9a 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java b/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java index cf3c03d7f..72409b168 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java @@ -20,7 +20,7 @@ import java.util.regex.Pattern; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.Parser.CoordinateFormat; diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java index 930d4f23b..b86584016 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index 9c94ffd4b..57e4c736f 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -25,7 +25,7 @@ import io.netty.handler.codec.mqtt.MqttMessageBuilders; import io.netty.handler.codec.mqtt.MqttPublishMessage; import io.netty.handler.codec.mqtt.MqttSubscribeMessage; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java index 9eed58347..1ed9a7d8c 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java index 63556e7a9..972f22ebe 100644 --- a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java index 40fa8864d..98fb36e11 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java b/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java index 33026918a..ffddcc568 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 2c1b5dcec..9fa550ded 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java b/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java index 63812242a..fb989c72e 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java index a14f9b8a4..d7c236c4f 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java index 5b5eb7d60..820de8f1c 100644 --- a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java index 132087c8f..809fafc90 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index d8554dc13..c55c0624d 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java index ad0c9bd32..6affb85c5 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java @@ -22,7 +22,7 @@ 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.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java b/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java index 1460bb176..9415d0f07 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java b/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java index 21e4a2fd0..7eca93a59 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java b/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java index 37b097414..78308658e 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java index 2c7b7eb40..8ac13b4d4 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java index 431258388..fac930ba8 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java index 7233280c2..06b6f0e76 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index 528098363..0b6bf8663 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 3ab449350..30689436d 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java index c72a742b9..84ba75e7c 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java b/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java index 901ceb8f7..21c629411 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java index d5be31cec..f2e5eb905 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index c63226c80..228578571 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index 86c89e336..d7600ecbb 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java b/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java index 3116d073c..8e6679b05 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; import org.w3c.dom.Document; diff --git a/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java b/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java index 8ce4fe8b1..9bca4d9bc 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java index 88419b871..896c7a2d2 100644 --- a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java @@ -26,7 +26,7 @@ import io.netty.handler.codec.http.HttpVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java b/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java index d1207bedf..e94d12b36 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java index 379b610e1..b3e2295e8 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java index db5521201..6dadbc559 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java index 7ba474ae0..53631bd4e 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java index 10d71d76c..47d10b310 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 5fb3e771f..9122eb362 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java b/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java index 6b5596dba..18ebc49da 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/NetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NetProtocolDecoder.java index c71a792a2..ebffb06f1 100644 --- a/src/main/java/org/traccar/protocol/NetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NetProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java index 47c6e2ffd..16d992938 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java index 53dae7fd6..53b58f9b6 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java b/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java index 5d1159f7d..f826c4121 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java index 62b41a2ea..49bc5b824 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java b/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java index 1c9771ce9..bf0ba6f82 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java index b9cc71e8c..b0c7c3bc6 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java index fa35ab455..3bb62acb9 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java index f90d1f2b3..9d747032b 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java index b76cbfa85..255a81ae6 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java @@ -20,7 +20,7 @@ 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.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 7277b1e5f..8ec47908f 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpResponse; import org.traccar.BasePipelineFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java index af819989e..681891edb 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index ec9bbc240..178ec344f 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.database.CommandsManager; import org.traccar.helper.DateUtil; diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java index 9de77d241..62b873be7 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java index 509d14ae4..71ac87168 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java index b5d34a029..7079745be 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java b/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java index 02a15e34a..3e7fa9a5b 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java @@ -24,7 +24,7 @@ import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 26ce2fe53..244df6806 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -22,7 +22,7 @@ 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.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java index 65de211ac..6ee95d18a 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java index ce45abef6..028de5424 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java index e1847a2b2..da9403313 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java index a19384e62..ff6ad763a 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java b/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java index 190c68258..5f6805f09 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java b/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java index 0025cd9e7..e3a5881da 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/PstProtocolDecoder.java b/src/main/java/org/traccar/protocol/PstProtocolDecoder.java index e3fe1af62..872e77a3a 100644 --- a/src/main/java/org/traccar/protocol/PstProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PstProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java index 48ce7dede..f669c5ffd 100644 --- a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java index e7f9e062a..c33660f51 100644 --- a/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index 0817d527d..21b91203f 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java index 6a3fe2734..94b549fe6 100644 --- a/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java b/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java index d60318447..3be784911 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java index f441bf8ed..89639ad30 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java b/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java index d87f77b84..818e97f8b 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java index 50acd20a1..dfc21bf69 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java index 04098225f..0c417a62f 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java index 5bf6cef50..afbf7e511 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java b/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java index 46267ca90..501d5faa7 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java index b613f31d7..ffe16bd7b 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java index 9e3261a04..fcc96fbf1 100644 --- a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 7abb52bd0..77df0deb7 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index 6d565517b..a88bfa65a 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; diff --git a/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java b/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java index 3033aa2cc..71279812c 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java b/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java index 7e1c158e6..6741cb67c 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java b/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java index 036d1ee51..9568cd6d3 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java index c457d5620..37a84be04 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index ce577f392..bbb8bc1cc 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java b/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java index bf8bfab77..7ba501834 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java index 818acd805..6ffcbbe44 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java b/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java index 04920c969..7fc38f061 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java b/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java index 9da52e97a..2244ad289 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java index 9d5dc072f..0432fbd03 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java b/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java index 34417d95f..d493b748d 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index afccb3a6b..0ff668fa8 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java index 5ffddb318..56ab733c8 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 8a7b5cec7..53c02f28c 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index cc985d605..c07337fc5 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java index 7b0055aa1..dc1fa3ba3 100644 --- a/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index fca7661f7..6340def86 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java b/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java index 40a25bb91..f53f0f598 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java b/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java index 7e783f6cd..d7b126167 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java @@ -24,7 +24,7 @@ import org.traccar.helper.PatternBuilder; import java.net.SocketAddress; import java.util.regex.Pattern; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.helper.Parser; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java index 8d0b31c8f..b1cff8b64 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index acfab5598..3d892c021 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java index 2a3cca3e4..d9fd1c8cf 100644 --- a/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index d554c2999..b7a89f2e9 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java index ec0ce1931..e5e84b7c4 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java index b6091136a..94efacc63 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java index 6b9f0edb6..09efcb7d4 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TekProtocolDecoder.java b/src/main/java/org/traccar/protocol/TekProtocolDecoder.java index 33ff51d2d..819c7e819 100644 --- a/src/main/java/org/traccar/protocol/TekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TekProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java index 9369ab101..f6f6f5379 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java index a4f9e2989..9681dc565 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 03a5a00ea..f91eef837 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index c36da2aed..313210f63 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index b3f943078..085ce4c91 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java index 82033598d..796b726ea 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java index da0c6928b..af29fbc21 100644 --- a/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index 476d1d682..e197a8a41 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index ad7dfa886..3d219fc09 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java index 36cf7859f..7870c778a 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java index d27849f8c..00dc2a09b 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java index 6de053c32..92a7b5c9d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 4fe261aa4..a1d5481db 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index b76d5b307..4f520f360 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java index 2f11bd152..0306770b6 100644 --- a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java index 319194c21..da0e8d292 100644 --- a/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java index db8022738..10483d445 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java index 4d5cb18f5..b1f50dc10 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index e42e2f670..21dd78da3 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateUtil; diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index e62cdf404..9df29ae1b 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java index 1010528c4..cbc983000 100644 --- a/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java index 93d3a63d2..6169e0545 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index b1ddc5203..8e84a6781 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java index 7fec0bf8b..e6cc0a891 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index 9f236a7e5..bdc6bf24e 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java b/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java index 1081fa811..b9065e7f3 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java b/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java index 40267022b..237aea39b 100644 --- a/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java index c4787bda2..9ab871bfe 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java b/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java index 1ee00bd3f..048c89e1e 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java index 84ad09caa..a8fc801e7 100644 --- a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java index 17fac4311..bf0cdcb51 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 3967fb804..35fdc3ca5 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 19d9dd6c8..8dd7aab24 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java index 976d4fb27..ec1c4d17a 100644 --- a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java index b85ae2656..22d7bade3 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java index 58b5784d0..323992ddd 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 766a3f05b..501897715 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java index 73d386477..e41d467d5 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java index b53a42ac3..220c28054 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.nio.NioDatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java index 69e5b7372..88f2d07e5 100644 --- a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java index f49fb9563..ab0b2cdaa 100644 --- a/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java index b3f6493a8..edcb3f535 100644 --- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java b/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java index bf5a23fa7..fd050bee9 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index dd1ef478f..413d49ad7 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -31,7 +31,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/session/ActiveDevice.java b/src/main/java/org/traccar/session/ActiveDevice.java new file mode 100644 index 000000000..af19ba55b --- /dev/null +++ b/src/main/java/org/traccar/session/ActiveDevice.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 - 2020 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.session; + +import io.netty.channel.Channel; +import io.netty.handler.codec.http.HttpRequestDecoder; +import org.traccar.BasePipelineFactory; +import org.traccar.Protocol; +import org.traccar.model.Command; + +import java.net.SocketAddress; + +public class ActiveDevice { + + private final long deviceId; + private final Protocol protocol; + private final Channel channel; + private final SocketAddress remoteAddress; + private final boolean supportsLiveCommands; + + public ActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { + this.deviceId = deviceId; + this.protocol = protocol; + this.channel = channel; + this.remoteAddress = remoteAddress; + supportsLiveCommands = BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; + } + + public Channel getChannel() { + return channel; + } + + public long getDeviceId() { + return deviceId; + } + + public boolean supportsLiveCommands() { + return supportsLiveCommands; + } + + public void sendCommand(Command command) { + protocol.sendDataCommand(channel, remoteAddress, command); + } + +} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java new file mode 100644 index 000000000..fbc15b00d --- /dev/null +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -0,0 +1,218 @@ +/* + * 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. + * 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.session; + +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.Main; +import org.traccar.Protocol; +import org.traccar.config.Keys; +import org.traccar.handler.events.MotionEventHandler; +import org.traccar.handler.events.OverspeedEventHandler; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.storage.StorageException; + +import java.net.SocketAddress; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +public class ConnectionManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); + + private final long deviceTimeout; + private final boolean updateDeviceState; + + private final Map activeDevices = new ConcurrentHashMap<>(); + 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) { + activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); + } + + public void removeActiveDevice(Channel channel) { + for (ActiveDevice activeDevice : activeDevices.values()) { + if (activeDevice.getChannel() == channel) { + updateDevice(activeDevice.getDeviceId(), Device.STATUS_OFFLINE, null); + activeDevices.remove(activeDevice.getDeviceId()); + break; + } + } + } + + public ActiveDevice getActiveDevice(long deviceId) { + return activeDevices.get(deviceId); + } + + public void updateDevice(final long deviceId, String status, Date time) { + Device device = Context.getIdentityManager().getById(deviceId); + if (device == null) { + return; + } + + String oldStatus = device.getStatus(); + device.setStatus(status); + + if (!status.equals(oldStatus)) { + String eventType; + Map events = new HashMap<>(); + switch (status) { + case Device.STATUS_ONLINE: + eventType = Event.TYPE_DEVICE_ONLINE; + break; + case Device.STATUS_UNKNOWN: + eventType = Event.TYPE_DEVICE_UNKNOWN; + if (updateDeviceState) { + events.putAll(updateDeviceState(deviceId)); + } + break; + default: + eventType = Event.TYPE_DEVICE_OFFLINE; + if (updateDeviceState) { + events.putAll(updateDeviceState(deviceId)); + } + break; + } + events.put(new Event(eventType, deviceId), null); + Context.getNotificationManager().updateEvents(events); + } + + Timeout timeout = timeouts.remove(deviceId); + if (timeout != null) { + timeout.cancel(); + } + + if (time != null) { + device.setLastUpdate(time); + } + + if (status.equals(Device.STATUS_ONLINE)) { + timeouts.put(deviceId, timer.newTimeout(timeout1 -> { + if (!timeout1.isCancelled()) { + updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + } + }, deviceTimeout, TimeUnit.MILLISECONDS)); + } + + try { + Context.getDeviceManager().updateDeviceStatus(device); + } catch (StorageException e) { + LOGGER.warn("Update device status error", e); + } + + updateDevice(device); + } + + public Map updateDeviceState(long deviceId) { + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + Map result = new HashMap<>(); + + Map event = Main.getInjector() + .getInstance(MotionEventHandler.class).updateMotionState(deviceState); + if (event != null) { + result.putAll(event); + } + + event = Main.getInjector().getInstance(OverspeedEventHandler.class) + .updateOverspeedState(deviceState, Context.getDeviceManager(). + lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false)); + if (event != null) { + result.putAll(event); + } + + return result; + } + + public synchronized void sendKeepalive() { + for (Set userListeners : listeners.values()) { + for (UpdateListener listener : userListeners) { + listener.onKeepalive(); + } + } + } + + public synchronized void updateDevice(Device device) { + for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { + listener.onUpdateDevice(device); + } + } + } + } + + public synchronized void updatePosition(Position position) { + long deviceId = position.getDeviceId(); + + for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { + listener.onUpdatePosition(position); + } + } + } + } + + public synchronized void updateEvent(long userId, Event event) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { + listener.onUpdateEvent(event); + } + } + } + + public interface UpdateListener { + void onKeepalive(); + void onUpdateDevice(Device device); + void onUpdatePosition(Position position); + void onUpdateEvent(Event event); + } + + public synchronized void addListener(long userId, UpdateListener listener) { + if (!listeners.containsKey(userId)) { + listeners.put(userId, new HashSet<>()); + } + listeners.get(userId).add(listener); + } + + public synchronized void removeListener(long userId, UpdateListener listener) { + if (!listeners.containsKey(userId)) { + listeners.put(userId, new HashSet<>()); + } + listeners.get(userId).remove(listener); + } + +} diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java new file mode 100644 index 000000000..6fe5b5d57 --- /dev/null +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -0,0 +1,42 @@ +/* + * 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.session; + +import java.util.TimeZone; + +public class DeviceSession { + + private final long deviceId; + + public DeviceSession(long deviceId) { + this.deviceId = deviceId; + } + + public long getDeviceId() { + return deviceId; + } + + private TimeZone timeZone; + + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + } + + public TimeZone getTimeZone() { + return timeZone; + } + +} diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java new file mode 100644 index 000000000..b7248688a --- /dev/null +++ b/src/main/java/org/traccar/session/DeviceState.java @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 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.session; + +import org.traccar.model.Position; + +public class DeviceState { + + private Boolean motionState; + + public void setMotionState(boolean motionState) { + this.motionState = motionState; + } + + public Boolean getMotionState() { + return motionState; + } + + private Position motionPosition; + + public void setMotionPosition(Position motionPosition) { + this.motionPosition = motionPosition; + } + + public Position getMotionPosition() { + return motionPosition; + } + + private Boolean overspeedState; + + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + } + + public Boolean getOverspeedState() { + return overspeedState; + } + + private Position overspeedPosition; + + public void setOverspeedPosition(Position overspeedPosition) { + this.overspeedPosition = overspeedPosition; + } + + public Position getOverspeedPosition() { + return overspeedPosition; + } + + private long overspeedGeofenceId; + + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + } + + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + +} diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 0f6c55857..a33bb2b5d 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,7 +1,7 @@ package org.traccar; import org.traccar.config.Config; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index f57c16635..8d84e3125 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -15,7 +15,7 @@ import java.util.TimeZone; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.model.TripsConfig; diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 515f37b5d..5c4cce1b6 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; -- cgit v1.2.3 From 2e83b23d258e74df6dfc1c860c2abf9b1b816181 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 16:45:55 -0700 Subject: Remove unused code --- .../java/org/traccar/database/DeviceManager.java | 45 +--------------------- 1 file changed, 2 insertions(+), 43 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 3b500aba9..0e5056e57 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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. @@ -46,7 +46,6 @@ public class DeviceManager extends BaseObjectManager implements Identity private final long dataRefreshDelay; private Map devicesByUniqueId; - private Map devicesByPhone; private final AtomicLong devicesLastUpdate = new AtomicLong(); private final Map positions = new ConcurrentHashMap<>(); @@ -58,9 +57,6 @@ public class DeviceManager extends BaseObjectManager implements Identity this.config = Context.getConfig(); try { writeLock(); - if (devicesByPhone == null) { - devicesByPhone = new ConcurrentHashMap<>(); - } if (devicesByUniqueId == null) { devicesByUniqueId = new ConcurrentHashMap<>(); } @@ -216,39 +212,10 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - private void addByPhone(Device device) { - try { - writeLock(); - if (devicesByPhone == null) { - devicesByPhone = new ConcurrentHashMap<>(); - } - devicesByPhone.put(device.getPhone(), device); - } finally { - writeUnlock(); - } - } - - private void removeByPhone(String phone) { - if (phone == null || phone.isEmpty()) { - return; - } - try { - writeLock(); - if (devicesByPhone != null) { - devicesByPhone.remove(phone); - } - } finally { - writeUnlock(); - } - } - @Override protected void addNewItem(Device device) { super.addNewItem(device); addByUniqueId(device); - if (device.getPhone() != null && !device.getPhone().isEmpty()) { - addByPhone(device); - } if (Context.getGeofenceManager() != null) { Position lastPosition = getLastPosition(device.getId()); if (lastPosition != null) { @@ -264,6 +231,7 @@ public class DeviceManager extends BaseObjectManager implements Identity cachedDevice.setGroupId(device.getGroupId()); cachedDevice.setCategory(device.getCategory()); cachedDevice.setContact(device.getContact()); + cachedDevice.setPhone(device.getPhone()); cachedDevice.setModel(device.getModel()); cachedDevice.setDisabled(device.getDisabled()); cachedDevice.setAttributes(device.getAttributes()); @@ -272,13 +240,6 @@ public class DeviceManager extends BaseObjectManager implements Identity cachedDevice.setUniqueId(device.getUniqueId()); addByUniqueId(cachedDevice); } - if (device.getPhone() != null && !device.getPhone().isEmpty() - && !device.getPhone().equals(cachedDevice.getPhone())) { - String phone = cachedDevice.getPhone(); - removeByPhone(phone); - cachedDevice.setPhone(device.getPhone()); - addByPhone(cachedDevice); - } } @Override @@ -286,10 +247,8 @@ public class DeviceManager extends BaseObjectManager implements Identity Device cachedDevice = getById(deviceId); if (cachedDevice != null) { String deviceUniqueId = cachedDevice.getUniqueId(); - String phone = cachedDevice.getPhone(); super.removeCachedItem(deviceId); removeByUniqueId(deviceUniqueId); - removeByPhone(phone); } positions.remove(deviceId); } -- cgit v1.2.3 From 9a68d1045f30bf8397d6cbf90df8f42f40979591 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 16:58:34 -0700 Subject: Add generic variable store --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 28 +++++++++++----------- .../traccar/protocol/HuabaoProtocolDecoder.java | 8 +++---- .../traccar/protocol/UlbotechProtocolDecoder.java | 8 ++++--- .../java/org/traccar/session/DeviceSession.java | 24 ++++++++++++++----- 4 files changed, 41 insertions(+), 27 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index c200c6ba9..0f89597ce 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -444,8 +444,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } position.setDeviceId(deviceSession.getDeviceId()); - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } } @@ -455,8 +455,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // type deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null && deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (deviceSession != null && !deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } if (dataLength > 10) { @@ -468,7 +468,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { offset = -offset; } if (deviceSession != null) { - TimeZone timeZone = deviceSession.getTimeZone(); + TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); if (timeZone.getRawOffset() == 0) { timeZone.setRawOffset(offset * 1000); deviceSession.setTimeZone(timeZone); @@ -531,7 +531,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // data and alarm - decodeGps(position, buf, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); buf.readUnsignedShort(); // terminal info @@ -653,7 +653,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5; - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); @@ -769,7 +769,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasGps(type)) { - decodeGps(position, buf, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); } else { getLastLocation(position, null); } @@ -858,9 +858,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { boolean extendedAlarm = dataLength > 7; if (extendedAlarm) { - decodeGps(position, buf, false, false, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, false, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); } else { - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); getLastLocation(position, dateBuilder.getDate()); @@ -925,8 +925,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } Position position = new Position(getProtocolName()); @@ -1033,7 +1033,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_AZ735_GPS || type == MSG_AZ735_ALARM) { - if (!decodeGps(position, buf, true, deviceSession.getTimeZone())) { + if (!decodeGps(position, buf, true, deviceSession.get(DeviceSession.KEY_TIMEZONE))) { getLastLocation(position, position.getDeviceTime()); } @@ -1078,7 +1078,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_OBD) { - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index c75fd673a..00093c978 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -198,8 +198,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId(), "GMT+8")); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId(), "GMT+8")); } if (type == MSG_TERMINAL_REGISTER) { @@ -407,7 +407,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(buf.readShort()); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort()); - position.setTime(readDate(buf, deviceSession.getTimeZone())); + position.setTime(readDate(buf, deviceSession.get(DeviceSession.KEY_TIMEZONE))); if (buf.readableBytes() == 20) { @@ -642,7 +642,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - Date time = readDate(buf, deviceSession.getTimeZone()); + Date time = readDate(buf, deviceSession.get(DeviceSession.KEY_TIMEZONE)); if (buf.readUnsignedByte() > 0) { position.set(Position.KEY_ARCHIVE, true); diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java index e6cc0a891..c9b35158e 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -37,6 +37,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.TimeZone; import java.util.regex.Pattern; public class UlbotechProtocolDecoder extends BaseProtocolDecoder { @@ -214,16 +215,17 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); long seconds = buf.readUnsignedInt() & 0x7fffffffL; seconds += 946684800L; // 2000-01-01 00:00 - seconds -= deviceSession.getTimeZone().getRawOffset() / 1000; + seconds -= timeZone.getRawOffset() / 1000; Date time = new Date(seconds * 1000); boolean hasLocation = false; diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java index 6fe5b5d57..0d5b283fe 100644 --- a/src/main/java/org/traccar/session/DeviceSession.java +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -15,7 +15,8 @@ */ package org.traccar.session; -import java.util.TimeZone; +import java.util.HashMap; +import java.util.Map; public class DeviceSession { @@ -29,14 +30,25 @@ public class DeviceSession { return deviceId; } - private TimeZone timeZone; + public static final String KEY_TIMEZONE = "timezone"; - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; + private final Map locals = new HashMap<>(); + + public boolean contains(String key) { + return locals.containsKey(key); + } + + public void set(String key, Object value) { + if (value != null) { + locals.put(key, value); + } else { + locals.remove(key); + } } - public TimeZone getTimeZone() { - return timeZone; + @SuppressWarnings("unchecked") + public T get(String key) { + return (T) locals.get(key); } } -- cgit v1.2.3 From 4dc602d8a7700924b0117424533046b28f4a8df4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 18:39:50 -0700 Subject: Combine active device and session --- src/main/java/org/traccar/BaseProtocolDecoder.java | 99 +--------------------- src/main/java/org/traccar/MainEventHandler.java | 2 +- src/main/java/org/traccar/config/Keys.java | 14 --- .../java/org/traccar/database/CommandsManager.java | 12 +-- .../java/org/traccar/database/DeviceManager.java | 6 +- .../java/org/traccar/database/IdentityManager.java | 2 +- .../org/traccar/protocol/EgtsProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- .../traccar/protocol/OrbcommProtocolDecoder.java | 3 +- .../java/org/traccar/session/ActiveDevice.java | 58 ------------- .../org/traccar/session/ConnectionManager.java | 81 +++++++++++++++--- .../java/org/traccar/session/DeviceSession.java | 40 ++++++++- src/main/java/org/traccar/session/Endpoint.java | 58 +++++++++++++ src/test/java/org/traccar/BaseTest.java | 27 +++++- 14 files changed, 208 insertions(+), 198 deletions(-) delete mode 100644 src/main/java/org/traccar/session/ActiveDevice.java create mode 100644 src/main/java/org/traccar/session/Endpoint.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 3fc6e7697..d6c571b79 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -18,14 +18,9 @@ package org.traccar; import com.google.inject.Inject; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import io.netty.channel.socket.DatagramChannel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; -import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; @@ -33,22 +28,19 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Collection; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.TimeZone; public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(BaseProtocolDecoder.class); - private static final String PROTOCOL_UNKNOWN = "unknown"; private final Protocol protocol; @@ -147,95 +139,8 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { return result; } - private DeviceSession channelDeviceSession; // connection-based protocols - private final Map addressDeviceSessions = new HashMap<>(); // connectionless protocols - - private long findDeviceId(SocketAddress remoteAddress, String... uniqueIds) { - if (uniqueIds.length > 0) { - long deviceId = 0; - Device device = null; - try { - for (String uniqueId : uniqueIds) { - if (uniqueId != null) { - device = identityManager.getByUniqueId(uniqueId); - if (device != null) { - deviceId = device.getId(); - break; - } - } - } - } catch (Exception e) { - LOGGER.warn("Find device error", e); - } - if (deviceId == 0 && config.getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { - return identityManager.addUnknownDevice(uniqueIds[0]); - } - if (device != null && !device.getDisabled()) { - return deviceId; - } - StringBuilder message = new StringBuilder(); - if (deviceId == 0) { - message.append("Unknown device -"); - } else { - message.append("Disabled device -"); - } - for (String uniqueId : uniqueIds) { - message.append(" ").append(uniqueId); - } - if (remoteAddress != null) { - message.append(" (").append(((InetSocketAddress) remoteAddress).getHostString()).append(")"); - } - LOGGER.warn(message.toString()); - } - return 0; - } - public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) { - return getDeviceSession(channel, remoteAddress, false, uniqueIds); - } - - public DeviceSession getDeviceSession( - Channel channel, SocketAddress remoteAddress, boolean ignoreCache, String... uniqueIds) { - if (channel != null && BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) != null - || ignoreCache || config.getBoolean(Keys.PROTOCOL_IGNORE_SESSIONS_CACHE.withPrefix(getProtocolName())) - || config.getBoolean(Keys.DECODER_IGNORE_SESSIONS_CACHE)) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - if (deviceId != 0) { - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - return new DeviceSession(deviceId); - } else { - return null; - } - } - if (channel instanceof DatagramChannel) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - DeviceSession deviceSession = addressDeviceSessions.get(remoteAddress); - if (deviceSession != null && (deviceSession.getDeviceId() == deviceId || uniqueIds.length == 0)) { - return deviceSession; - } else if (deviceId != 0) { - deviceSession = new DeviceSession(deviceId); - addressDeviceSessions.put(remoteAddress, deviceSession); - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - return deviceSession; - } else { - return null; - } - } else { - if (channelDeviceSession == null) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - if (deviceId != 0) { - channelDeviceSession = new DeviceSession(deviceId); - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - } - } - return channelDeviceSession; - } + return connectionManager.getDeviceSession(protocol, channel, remoteAddress, uniqueIds); } public void getLastLocation(Position position, Date deviceTime) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 91706222a..0a25b7547 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -130,7 +130,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - Context.getConnectionManager().removeActiveDevice(ctx.channel()); + Context.getConnectionManager().removeDeviceSessions(ctx.channel()); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index eebdf7172..f5370874d 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -190,13 +190,6 @@ public final class Keys { ".server", Collections.singletonList(KeyType.GLOBAL)); - /** - * Skip device connection session cache. Per protocol configuration. - */ - public static final ConfigSuffix PROTOCOL_IGNORE_SESSIONS_CACHE = new ConfigSuffix<>( - ".ignoreSessionCache", - Collections.singletonList(KeyType.GLOBAL)); - /** * ORBCOMM API access id. */ @@ -211,13 +204,6 @@ public final class Keys { "orbcomm.password", Collections.singletonList(KeyType.GLOBAL)); - /** - * Skip device connection session cache. Global configuration. - */ - public static final ConfigKey DECODER_IGNORE_SESSIONS_CACHE = new ConfigKey<>( - "decoder.ignoreSessionCache", - Collections.singletonList(KeyType.GLOBAL)); - /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 3adf5d2e9..57ce0f9a4 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 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"); @@ -34,7 +34,7 @@ import org.traccar.Context; import org.traccar.model.Command; import org.traccar.model.Typed; import org.traccar.model.Position; -import org.traccar.session.ActiveDevice; +import org.traccar.session.DeviceSession; public class CommandsManager extends ExtendedObjectManager { @@ -75,10 +75,10 @@ public class CommandsManager extends ExtendedObjectManager { throw new RuntimeException("Command " + command.getType() + " is not supported"); } } else { - ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(deviceId); - if (activeDevice != null) { - if (activeDevice.supportsLiveCommands()) { - activeDevice.sendCommand(command); + DeviceSession deviceSession = Context.getConnectionManager().getDeviceSession(deviceId); + if (deviceSession != null) { + if (deviceSession.supportsLiveCommands()) { + deviceSession.sendCommand(command); } else { getDeviceQueue(deviceId).add(command); return false; diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 0e5056e57..b1ea0b8b7 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -68,7 +68,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } @Override - public long addUnknownDevice(String uniqueId) { + public Device addUnknownDevice(String uniqueId) { Device device = new Device(); device.setName(uniqueId); device.setUniqueId(uniqueId); @@ -89,10 +89,10 @@ public class DeviceManager extends BaseObjectManager implements Identity Context.getPermissionsManager().refreshAllExtendedPermissions(); } - return device.getId(); + return device; } catch (StorageException e) { LOGGER.warn("Automatic device registration error", e); - return 0; + return null; } } diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index af6a6ce71..ee386fdfd 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -20,7 +20,7 @@ import org.traccar.model.Position; public interface IdentityManager { - long addUnknownDevice(String uniqueId); + Device addUnknownDevice(String uniqueId); Device getById(long id); diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java index 3a6af60a1..01d329580 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java @@ -291,7 +291,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { if (serviceType == SERVICE_TELEDATA && position.getValid()) { if (useObjectIdAsDeviceId && objectId != 0L) { - deviceSession = getDeviceSession(channel, remoteAddress, true, String.valueOf(objectId)); + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(objectId)); if (deviceSession != null) { position.setDeviceId(deviceSession.getDeviceId()); } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 0f89597ce..4b9757874 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -471,7 +471,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); if (timeZone.getRawOffset() == 0) { timeZone.setRawOffset(offset * 1000); - deviceSession.setTimeZone(timeZone); + deviceSession.set(DeviceSession.KEY_TIMEZONE, timeZone); } } } diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 8ec47908f..1164d72a1 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -70,8 +70,7 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { JsonArray messages = json.getJsonArray("Messages"); for (int i = 0; i < messages.size(); i++) { JsonObject message = messages.getJsonObject(i); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, true, message.getString("MobileID")); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, message.getString("MobileID")); if (deviceSession != null) { Position position = new Position(getProtocolName()); diff --git a/src/main/java/org/traccar/session/ActiveDevice.java b/src/main/java/org/traccar/session/ActiveDevice.java deleted file mode 100644 index af19ba55b..000000000 --- a/src/main/java/org/traccar/session/ActiveDevice.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 - 2020 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.session; - -import io.netty.channel.Channel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import org.traccar.BasePipelineFactory; -import org.traccar.Protocol; -import org.traccar.model.Command; - -import java.net.SocketAddress; - -public class ActiveDevice { - - private final long deviceId; - private final Protocol protocol; - private final Channel channel; - private final SocketAddress remoteAddress; - private final boolean supportsLiveCommands; - - public ActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - this.deviceId = deviceId; - this.protocol = protocol; - this.channel = channel; - this.remoteAddress = remoteAddress; - supportsLiveCommands = BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; - } - - public Channel getChannel() { - return channel; - } - - public long getDeviceId() { - return deviceId; - } - - public boolean supportsLiveCommands() { - return supportsLiveCommands; - } - - public void sendCommand(Command command) { - protocol.sendDataCommand(channel, remoteAddress, command); - } - -} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index fbc15b00d..5d8a8c606 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -31,6 +31,7 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Date; import java.util.HashMap; @@ -47,7 +48,9 @@ public class ConnectionManager { private final long deviceTimeout; private final boolean updateDeviceState; - private final Map activeDevices = new ConcurrentHashMap<>(); + private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); + private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); @@ -59,22 +62,78 @@ public class ConnectionManager { timer = Main.getInjector().getInstance(Timer.class); } - public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); + public DeviceSession getDeviceSession(long deviceId) { + return sessionsByDeviceId.get(deviceId); } - public void removeActiveDevice(Channel channel) { - for (ActiveDevice activeDevice : activeDevices.values()) { - if (activeDevice.getChannel() == channel) { - updateDevice(activeDevice.getDeviceId(), Device.STATUS_OFFLINE, null); - activeDevices.remove(activeDevice.getDeviceId()); - break; + public DeviceSession getDeviceSession( + Protocol protocol, Channel channel, SocketAddress remoteAddress, String... uniqueIds) { + + Endpoint endpoint = new Endpoint(channel, remoteAddress); + Map endpointSessions = sessionsByEndpoint.getOrDefault( + endpoint, new ConcurrentHashMap<>()); + if (uniqueIds.length > 0) { + for (String uniqueId : uniqueIds) { + DeviceSession deviceSession = endpointSessions.get(uniqueId); + if (deviceSession != null) { + return deviceSession; + } } + } else { + return endpointSessions.values().stream().findAny().orElse(null); + } + + Device device = null; + try { + for (String uniqueId : uniqueIds) { + device = Context.getIdentityManager().getByUniqueId(uniqueId); + if (device != null) { + break; + } + } + } catch (Exception e) { + LOGGER.warn("Find device error", e); + } + + if (device == null && Context.getConfig().getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { + device = Context.getIdentityManager().addUnknownDevice(uniqueIds[0]); + } + + if (device != null && !device.getDisabled()) { + DeviceSession oldSession = sessionsByDeviceId.remove(device.getId()); + if (oldSession != null) { + Endpoint oldEndpoint = new Endpoint(oldSession.getChannel(), oldSession.getRemoteAddress()); + Map oldEndpointSessions = sessionsByEndpoint.get(oldEndpoint); + if (oldEndpointSessions.size() > 1) { + oldEndpointSessions.remove(device.getUniqueId()); + } else { + sessionsByEndpoint.remove(oldEndpoint); + } + } + + DeviceSession deviceSession = new DeviceSession( + device.getId(), device.getUniqueId(), protocol, channel, remoteAddress); + endpointSessions.put(device.getUniqueId(), deviceSession); + sessionsByEndpoint.put(endpoint, endpointSessions); + sessionsByDeviceId.put(device.getId(), deviceSession); + + return deviceSession; + } else { + LOGGER.warn((device == null ? "Unknown" : "Disabled") + " device - " + String.join(" ", uniqueIds) + + " (" + ((InetSocketAddress) remoteAddress).getHostString() + ")"); + return null; } } - public ActiveDevice getActiveDevice(long deviceId) { - return activeDevices.get(deviceId); + public void removeDeviceSessions(Channel channel) { + Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); + Map endpointSessions = sessionsByEndpoint.remove(endpoint); + if (endpointSessions != null) { + for (DeviceSession deviceSession : endpointSessions.values()) { + updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); + sessionsByDeviceId.remove(deviceSession.getDeviceId()); + } + } } public void updateDevice(final long deviceId, String status, Date time) { diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java index 0d5b283fe..009f90f5a 100644 --- a/src/main/java/org/traccar/session/DeviceSession.java +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 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. @@ -15,21 +15,57 @@ */ package org.traccar.session; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.HttpRequestDecoder; +import org.traccar.BasePipelineFactory; +import org.traccar.Protocol; +import org.traccar.model.Command; + +import java.net.SocketAddress; import java.util.HashMap; import java.util.Map; public class DeviceSession { private final long deviceId; + private final String uniqueId; + private final Protocol protocol; + private final Channel channel; + private final SocketAddress remoteAddress; - public DeviceSession(long deviceId) { + public DeviceSession( + long deviceId, String uniqueId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { this.deviceId = deviceId; + this.uniqueId = uniqueId; + this.protocol = protocol; + this.channel = channel; + this.remoteAddress = remoteAddress; } public long getDeviceId() { return deviceId; } + public String getUniqueId() { + return uniqueId; + } + + public Channel getChannel() { + return channel; + } + + public SocketAddress getRemoteAddress() { + return remoteAddress; + } + + public boolean supportsLiveCommands() { + return BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; + } + + public void sendCommand(Command command) { + protocol.sendDataCommand(channel, remoteAddress, command); + } + public static final String KEY_TIMEZONE = "timezone"; private final Map locals = new HashMap<>(); diff --git a/src/main/java/org/traccar/session/Endpoint.java b/src/main/java/org/traccar/session/Endpoint.java new file mode 100644 index 000000000..76aac3444 --- /dev/null +++ b/src/main/java/org/traccar/session/Endpoint.java @@ -0,0 +1,58 @@ +/* + * 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.session; + +import io.netty.channel.Channel; + +import java.net.SocketAddress; +import java.util.Objects; + +public class Endpoint { + + private final Channel channel; + private final SocketAddress remoteAddress; + + public Endpoint(Channel channel, SocketAddress remoteAddress) { + this.channel = channel; + this.remoteAddress = remoteAddress; + } + + public Channel getChannel() { + return channel; + } + + public SocketAddress getRemoteAddress() { + return remoteAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Endpoint endpoint = (Endpoint) o; + return channel.equals(endpoint.channel) && remoteAddress.equals(endpoint.remoteAddress); + } + + @Override + public int hashCode() { + return Objects.hash(channel, remoteAddress); + } + +} diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index a33bb2b5d..40ac76601 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,11 +1,22 @@ package org.traccar; +import io.netty.channel.Channel; +import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.traccar.config.Config; import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.model.Device; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.TimeZone; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -30,7 +41,21 @@ public class BaseTest { when(identityManager.lookupAttributeInteger(anyLong(), any(), anyInt(), anyBoolean(), anyBoolean())) .thenAnswer(invocation -> invocation.getArguments()[2]); decoder.setIdentityManager(identityManager); - decoder.setConnectionManager(mock(ConnectionManager.class)); + var connectionManager = mock(ConnectionManager.class); + var uniqueIdsProvided = new HashSet(); + when(connectionManager.getDeviceSession(any(), any(), any(), any())).thenAnswer(invocation -> { + var mock = new DeviceSession(1L, "", mock(Protocol.class), mock(Channel.class), mock(SocketAddress.class)); + if (uniqueIdsProvided.isEmpty()) { + if (invocation.getArguments().length > 3) { + uniqueIdsProvided.add(true); + return mock; + } + return null; + } else { + return mock; + } + }); + decoder.setConnectionManager(connectionManager); decoder.setStatisticsManager(mock(StatisticsManager.class)); decoder.setMediaManager(mock(MediaManager.class)); return decoder; -- cgit v1.2.3 From 5032f99c6462ca97f3629abe1faf2f50cc4977fe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 1 Jun 2022 19:07:59 -0700 Subject: New caching system --- .../java/org/traccar/session/cache/CacheKey.java | 57 ++++++ .../org/traccar/session/cache/CacheManager.java | 214 +++++++++++++++++++++ .../java/org/traccar/session/cache/CacheValue.java | 49 +++++ .../java/org/traccar/storage/query/Condition.java | 4 + 4 files changed, 324 insertions(+) create mode 100644 src/main/java/org/traccar/session/cache/CacheKey.java create mode 100644 src/main/java/org/traccar/session/cache/CacheManager.java create mode 100644 src/main/java/org/traccar/session/cache/CacheValue.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheKey.java b/src/main/java/org/traccar/session/cache/CacheKey.java new file mode 100644 index 000000000..23145e34b --- /dev/null +++ b/src/main/java/org/traccar/session/cache/CacheKey.java @@ -0,0 +1,57 @@ +/* + * 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.session.cache; + +import org.traccar.model.BaseModel; + +import java.util.Objects; + +class CacheKey { + + private final Class clazz; + private final long id; + + CacheKey(BaseModel object) { + this(object.getClass(), object.getId()); + } + + CacheKey(Class clazz, long id) { + this.clazz = clazz; + this.id = id; + } + + public boolean classIs(Class clazz) { + return clazz.equals(this.clazz); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheKey cacheKey = (CacheKey) o; + return id == cacheKey.id && Objects.equals(clazz, cacheKey.clazz); + } + + @Override + public int hashCode() { + return Objects.hash(clazz, id); + } + +} diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java new file mode 100644 index 000000000..ae514ce8b --- /dev/null +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -0,0 +1,214 @@ +/* + * 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.session.cache; + +import org.traccar.model.Attribute; +import org.traccar.model.BaseModel; +import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Driver; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; +import org.traccar.model.Notification; +import org.traccar.model.Order; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; + +@Singleton +public class CacheManager { + + private static final Collection> CLASSES = Arrays.asList( + Attribute.class, Command.class, Driver.class, Geofence.class, + Maintenance.class, Notification.class, Order.class); + + private final Storage storage; + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + + private final Map deviceCache = new HashMap<>(); + private final Map, List>> deviceLinks = new HashMap<>(); + + private final Map> userNotifications = new HashMap<>(); + + @Inject + public CacheManager(Storage storage) throws StorageException { + this.storage = storage; + invalidateUsers(); + } + + public T getObject(Class clazz, long id) { + try { + lock.readLock().lock(); + return deviceCache.get(new CacheKey(clazz, id)).getValue(); + } finally { + lock.readLock().unlock(); + } + } + + public List getDeviceObjects(long deviceId, Class clazz) { + try { + lock.readLock().lock(); + return deviceLinks.get(deviceId).get(clazz).stream() + .map(id -> deviceCache.get(new CacheKey(clazz, id)).getValue()) + .collect(Collectors.toList()); + } finally { + lock.readLock().unlock(); + } + } + + public List getUserNotifications(long userId) { + try { + lock.readLock().lock(); + return userNotifications.get(userId); + } finally { + lock.readLock().unlock(); + } + } + + public void addDevice(long deviceId) throws StorageException { + try { + lock.writeLock().lock(); + unsafeAddDevice(deviceId); + } finally { + lock.writeLock().unlock(); + } + } + + public void removeDevice(long deviceId) { + try { + lock.writeLock().lock(); + unsafeRemoveDevice(deviceId); + } finally { + lock.writeLock().unlock(); + } + } + + public void invalidate( + Class clazz, long id) throws StorageException { + invalidate(new CacheKey(clazz, id)); + } + + public void invalidate( + Class clazz1, long id1, + Class clazz2, long id2) throws StorageException { + invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); + } + + private void invalidateUsers() throws StorageException { + Map notifications = new HashMap<>(); + storage.getObjects(Notification.class, new Request(new Columns.All())) + .forEach(notification -> notifications.put(notification.getId(), notification)); + storage.getPermissions(User.class, Notification.class).forEach(permission -> { + long userId = permission.getOwnerId(); + var notification = notifications.get(permission.getPropertyId()); + userNotifications.computeIfAbsent(userId, k -> new LinkedList<>()).add(notification); + }); + } + + private void addObject(long deviceId, BaseModel object) { + deviceCache.computeIfAbsent(new CacheKey(object), k -> new CacheValue(object)).retain(deviceId); + } + + private void unsafeAddDevice(long deviceId) throws StorageException { + Map, List> links = new HashMap<>(); + + addObject(deviceId, storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId)))); + + for (Class clazz : CLASSES) { + var objects = storage.getObjects(clazz, new Request( + new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); + links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); + objects.forEach(object -> addObject(deviceId, object)); + } + + var users = storage.getObjects(User.class, new Request( + new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); + links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); + for (var user : users) { + var notifications = storage.getObjects(Notification.class, new Request( + new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); + notifications.stream() + .filter(Notification::getAlways) + .forEach(object -> { + links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); + addObject(deviceId, object); + }); + } + + deviceLinks.put(deviceId, links); + } + + private void unsafeRemoveDevice(long deviceId) { + deviceCache.remove(new CacheKey(Device.class, deviceId)); + deviceLinks.remove(deviceId).forEach((clazz, ids) -> ids.forEach(id -> { + var key = new CacheKey(clazz, id); + deviceCache.computeIfPresent(key, (k, value) -> { + value.release(deviceId); + return value.getReferences().size() > 0 ? value : null; + }); + })); + } + + private void invalidate(CacheKey... keys) throws StorageException { + try { + lock.writeLock().lock(); + unsafeInvalidate(keys); + } finally { + lock.writeLock().unlock(); + } + } + + private void unsafeInvalidate(CacheKey[] keys) throws StorageException { + boolean invalidateUsers = false; + Set linkedDevices = new HashSet<>(); + for (var key : keys) { + if (key.classIs(User.class) || key.classIs(Notification.class)) { + invalidateUsers = true; + } + deviceCache.computeIfPresent(key, (k, value) -> { + linkedDevices.addAll(value.getReferences()); + return value; + }); + } + for (long deviceId : linkedDevices) { + unsafeRemoveDevice(deviceId); + unsafeAddDevice(deviceId); + } + if (invalidateUsers) { + invalidateUsers(); + } + } + +} diff --git a/src/main/java/org/traccar/session/cache/CacheValue.java b/src/main/java/org/traccar/session/cache/CacheValue.java new file mode 100644 index 000000000..9e955dfe5 --- /dev/null +++ b/src/main/java/org/traccar/session/cache/CacheValue.java @@ -0,0 +1,49 @@ +/* + * 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.session.cache; + +import org.traccar.model.BaseModel; + +import java.util.HashSet; +import java.util.Set; + +class CacheValue { + + private final BaseModel value; + private final Set references = new HashSet<>(); + + CacheValue(BaseModel value) { + this.value = value; + } + + public void retain(long deviceId) { + references.add(deviceId); + } + + public void release(long deviceId) { + references.remove(deviceId); + } + + @SuppressWarnings("unchecked") + public T getValue() { + return (T) value; + } + + public Set getReferences() { + return references; + } + +} diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 4cfdc907f..91ede236c 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -165,6 +165,10 @@ public interface Condition { this(ownerClass, ownerId, propertyClass, 0, false); } + public Permission(Class ownerClass, Class propertyClass, long propertyId) { + this(ownerClass, 0, propertyClass, propertyId, false); + } + public Permission excludeGroups() { return new Permission(this.ownerClass, this.ownerId, this.propertyClass, this.propertyId, true); } -- cgit v1.2.3 From 6e1d43d86414281ca562c45488b82808936fc980 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:11:17 -0700 Subject: Integrate cache manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 7 +++++- src/main/java/org/traccar/MainEventHandler.java | 2 +- .../org/traccar/session/ConnectionManager.java | 26 +++++++++++++++++++--- .../org/traccar/session/cache/CacheManager.java | 8 +++++-- 4 files changed, 36 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index d6c571b79..71ef686fa 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -30,6 +30,7 @@ import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; +import org.traccar.storage.StorageException; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -140,7 +141,11 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) { - return connectionManager.getDeviceSession(protocol, channel, remoteAddress, uniqueIds); + try { + return connectionManager.getDeviceSession(protocol, channel, remoteAddress, uniqueIds); + } catch (StorageException e) { + throw new RuntimeException(e); + } } public void getLastLocation(Position position, Date deviceTime) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 0a25b7547..f04307fdb 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -130,7 +130,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - Context.getConnectionManager().removeDeviceSessions(ctx.channel()); + Context.getConnectionManager().deviceDisconnected(ctx.channel()); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 5d8a8c606..e01a568aa 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -29,6 +29,7 @@ import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import java.net.InetSocketAddress; @@ -51,6 +52,8 @@ public class ConnectionManager { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final CacheManager cacheManager; + private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); @@ -60,6 +63,7 @@ public class ConnectionManager { deviceTimeout = Context.getConfig().getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = Context.getConfig().getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); timer = Main.getInjector().getInstance(Timer.class); + cacheManager = Main.getInjector().getInstance(CacheManager.class); } public DeviceSession getDeviceSession(long deviceId) { @@ -67,7 +71,8 @@ public class ConnectionManager { } public DeviceSession getDeviceSession( - Protocol protocol, Channel channel, SocketAddress remoteAddress, String... uniqueIds) { + Protocol protocol, Channel channel, SocketAddress remoteAddress, + String... uniqueIds) throws StorageException { Endpoint endpoint = new Endpoint(channel, remoteAddress); Map endpointSessions = sessionsByEndpoint.getOrDefault( @@ -116,6 +121,7 @@ public class ConnectionManager { endpointSessions.put(device.getUniqueId(), deviceSession); sessionsByEndpoint.put(endpoint, endpointSessions); sessionsByDeviceId.put(device.getId(), deviceSession); + cacheManager.addDevice(device.getId()); return deviceSession; } else { @@ -125,17 +131,31 @@ public class ConnectionManager { } } - public void removeDeviceSessions(Channel channel) { + public void deviceDisconnected(Channel channel) { Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); Map endpointSessions = sessionsByEndpoint.remove(endpoint); if (endpointSessions != null) { for (DeviceSession deviceSession : endpointSessions.values()) { updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); sessionsByDeviceId.remove(deviceSession.getDeviceId()); + cacheManager.removeDevice(deviceSession.getDeviceId()); } } } + public void deviceUnknown(long deviceId) { + updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); + cacheManager.removeDevice(deviceId); + if (deviceSession != null) { + Endpoint endpoint = new Endpoint(deviceSession.getChannel(), deviceSession.getRemoteAddress()); + sessionsByEndpoint.computeIfPresent(endpoint, (e, sessions) -> { + sessions.remove(deviceSession.getUniqueId()); + return sessions.isEmpty() ? null : sessions; + }); + } + } + public void updateDevice(final long deviceId, String status, Date time) { Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { @@ -181,7 +201,7 @@ public class ConnectionManager { if (status.equals(Device.STATUS_ONLINE)) { timeouts.put(deviceId, timer.newTimeout(timeout1 -> { if (!timeout1.isCancelled()) { - updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + deviceUnknown(deviceId); } }, deviceTimeout, TimeUnit.MILLISECONDS)); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index ae514ce8b..d019b072b 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -99,7 +99,9 @@ public class CacheManager { public void addDevice(long deviceId) throws StorageException { try { lock.writeLock().lock(); - unsafeAddDevice(deviceId); + if (!deviceLinks.containsKey(deviceId)) { + unsafeAddDevice(deviceId); + } } finally { lock.writeLock().unlock(); } @@ -108,7 +110,9 @@ public class CacheManager { public void removeDevice(long deviceId) { try { lock.writeLock().lock(); - unsafeRemoveDevice(deviceId); + if (deviceLinks.containsKey(deviceId)) { + unsafeRemoveDevice(deviceId); + } } finally { lock.writeLock().unlock(); } -- cgit v1.2.3 From 946b0ebb443aaeb27bcc0e736eda8e929da8738c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:22:59 -0700 Subject: Fix permission query --- src/main/java/org/traccar/storage/DatabaseStorage.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index cd82448e1..34ae7c784 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -323,7 +323,6 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(expandDevices ? "devices." : "all_groups."); // TODO handle reverse (e.g. users by device) result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From 43942f459f456b05c62ea7549123e28fd7560d56 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:38:12 -0700 Subject: Inverse user notification cache --- .../java/org/traccar/session/cache/CacheManager.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index d019b072b..f6f04cc36 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -59,7 +59,7 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); - private final Map> userNotifications = new HashMap<>(); + private final Map> notificationUsers = new HashMap<>(); @Inject public CacheManager(Storage storage) throws StorageException { @@ -87,10 +87,10 @@ public class CacheManager { } } - public List getUserNotifications(long userId) { + public List getNotificationUsers(long notificationId) { try { lock.readLock().lock(); - return userNotifications.get(userId); + return notificationUsers.get(notificationId); } finally { lock.readLock().unlock(); } @@ -130,13 +130,13 @@ public class CacheManager { } private void invalidateUsers() throws StorageException { - Map notifications = new HashMap<>(); - storage.getObjects(Notification.class, new Request(new Columns.All())) - .forEach(notification -> notifications.put(notification.getId(), notification)); + Map users = new HashMap<>(); + storage.getObjects(User.class, new Request(new Columns.All())) + .forEach(user -> users.put(user.getId(), user)); storage.getPermissions(User.class, Notification.class).forEach(permission -> { - long userId = permission.getOwnerId(); - var notification = notifications.get(permission.getPropertyId()); - userNotifications.computeIfAbsent(userId, k -> new LinkedList<>()).add(notification); + long notificationId = permission.getPropertyId();; + var user = users.get(permission.getOwnerId()); + notificationUsers.computeIfAbsent(notificationId, k -> new LinkedList<>()).add(user); }); } -- cgit v1.2.3 From 026dc29deee601d3351274a888a73b434c1addfa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:41:10 -0700 Subject: Add position cache --- .../java/org/traccar/session/cache/CacheManager.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index f6f04cc36..273c54c9a 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -24,6 +24,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Order; +import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -59,6 +60,7 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); + private final Map devicePositions = new HashMap<>(); private final Map> notificationUsers = new HashMap<>(); @Inject @@ -87,6 +89,15 @@ public class CacheManager { } } + public Position getPosition(long deviceId) { + try { + lock.readLock().lock(); + return devicePositions.get(deviceId); + } finally { + lock.readLock().unlock(); + } + } + public List getNotificationUsers(long notificationId) { try { lock.readLock().lock(); @@ -118,6 +129,15 @@ public class CacheManager { } } + public void updatePosition(Position position) { + try { + lock.writeLock().lock(); + devicePositions.put(position.getDeviceId(), position); + } finally { + lock.writeLock().unlock(); + } + } + public void invalidate( Class clazz, long id) throws StorageException { invalidate(new CacheKey(clazz, id)); -- cgit v1.2.3 From b7119d6fe834d6ece8b80d5774b143e491eb2a93 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:46:11 -0700 Subject: Fix style issue --- src/main/java/org/traccar/session/cache/CacheManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 273c54c9a..4669024d3 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -154,7 +154,7 @@ public class CacheManager { storage.getObjects(User.class, new Request(new Columns.All())) .forEach(user -> users.put(user.getId(), user)); storage.getPermissions(User.class, Notification.class).forEach(permission -> { - long notificationId = permission.getPropertyId();; + long notificationId = permission.getPropertyId(); var user = users.get(permission.getOwnerId()); notificationUsers.computeIfAbsent(notificationId, k -> new LinkedList<>()).add(user); }); -- cgit v1.2.3 From ac065e6d945e66870f39c19578694759cd80f552 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Jun 2022 15:30:54 -0700 Subject: Fix permission query issue --- src/main/java/org/traccar/storage/DatabaseStorage.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 34ae7c784..2b9172153 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -299,10 +299,11 @@ public class DatabaseStorage extends Storage { conditionKey = Permission.getKey(condition.getPropertyClass()); } + String storageName = Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass()); result.append("SELECT "); - result.append(outputKey); + result.append(storageName).append('.').append(outputKey); result.append(" FROM "); - result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); + result.append(storageName); result.append(" WHERE "); result.append(conditionKey); result.append(" = :"); @@ -323,7 +324,7 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(outputKey); + result.append(groupStorageName).append('.').append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From 65b0f9c5398ddcb28018cb1963108534c638b1f4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Jun 2022 16:32:02 -0700 Subject: Fix another permission issue --- src/main/java/org/traccar/storage/DatabaseStorage.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 2b9172153..e4e4f3294 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -324,7 +324,10 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(groupStorageName).append('.').append(outputKey); + if (!expandDevices) { + result.append(groupStorageName).append('.'); + } + result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From 4030d3207c157a3fcee2653c18440898b6b2a2e6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Jun 2022 17:06:30 -0700 Subject: Remove attributes manager --- src/main/java/org/traccar/Context.java | 14 +------- src/main/java/org/traccar/MainModule.java | 6 ---- .../java/org/traccar/api/BaseObjectResource.java | 36 ++++++++++++++----- .../org/traccar/api/ExtendedObjectResource.java | 2 +- .../java/org/traccar/api/SimpleObjectResource.java | 2 +- .../traccar/api/resource/AttributeResource.java | 6 ++-- .../traccar/api/resource/PermissionsResource.java | 40 ++++++++-------------- .../traccar/api/security/PermissionsService.java | 19 ++++------ .../org/traccar/database/AttributesManager.java | 36 ------------------- .../java/org/traccar/database/DataManager.java | 5 +-- .../org/traccar/database/PermissionsManager.java | 25 -------------- .../traccar/handler/ComputedAttributesHandler.java | 11 +++--- src/main/java/org/traccar/model/Permission.java | 16 +++++---- .../java/org/traccar/storage/DatabaseStorage.java | 4 ++- .../java/org/traccar/storage/MemoryStorage.java | 4 ++- src/main/java/org/traccar/storage/Storage.java | 13 ++++--- 16 files changed, 85 insertions(+), 154 deletions(-) delete mode 100644 src/main/java/org/traccar/database/AttributesManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 1faa4c9de..4eab36a89 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 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. @@ -23,7 +23,6 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.AttributesManager; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; import org.traccar.database.CommandsManager; @@ -44,7 +43,6 @@ import org.traccar.database.UsersManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; -import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; @@ -213,12 +211,6 @@ public final class Context { return eventForwarder; } - private static AttributesManager attributesManager; - - public static AttributesManager getAttributesManager() { - return attributesManager; - } - private static DriversManager driversManager; public static DriversManager getDriversManager() { @@ -343,8 +335,6 @@ public final class Context { eventForwarder = new EventForwarder(); } - attributesManager = new AttributesManager(dataManager); - driversManager = new DriversManager(dataManager); commandsManager = new CommandsManager(dataManager, config.getBoolean(Keys.COMMANDS_QUEUEING)); @@ -398,8 +388,6 @@ public final class Context { return (BaseObjectManager) usersManager; } else if (clazz.equals(Calendar.class)) { return (BaseObjectManager) calendarManager; - } else if (clazz.equals(Attribute.class)) { - return (BaseObjectManager) attributesManager; } else if (clazz.equals(Geofence.class)) { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 43ca3ba77..f46312221 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -24,7 +24,6 @@ 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; import org.traccar.database.CalendarManager; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; @@ -130,11 +129,6 @@ public class MainModule extends AbstractModule { return Context.getCalendarManager(); } - @Provides - public static AttributesManager provideAttributesManager() { - return Context.getAttributesManager(); - } - @Provides public static MaintenancesManager provideMaintenancesManager() { return Context.getMaintenancesManager(); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 07c74449c..d6401dc42 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -66,7 +66,12 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), entity, true); BaseObjectManager manager = Context.getManager(baseClass); - manager.addItem(entity); + if (manager != null) { + manager.addItem(entity); + } else { + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); + } + LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); @@ -87,7 +92,15 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); - Context.getManager(baseClass).updateItem(entity); + BaseObjectManager manager = Context.getManager(baseClass); + if (manager != null) { + manager.updateItem(entity); + } else { + storage.updateObject(entity, new Request( + new Columns.Exclude("id"), + new Condition.Equals("id", "id"))); + } + LogAction.edit(getUserId(), entity); if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { @@ -104,15 +117,20 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkPermission(baseClass, getUserId(), id); BaseObjectManager manager = Context.getManager(baseClass); - manager.removeItem(id); - LogAction.remove(getUserId(), baseClass, id); - - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager) manager).refreshUserItems(); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager) manager).refreshExtendedPermissions(); + if (manager != null) { + manager.removeItem(id); + if (manager instanceof SimpleObjectManager) { + ((SimpleObjectManager) manager).refreshUserItems(); + if (manager instanceof ExtendedObjectManager) { + ((ExtendedObjectManager) manager).refreshExtendedPermissions(); + } } + } else { + storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } + + LogAction.remove(getUserId(), baseClass, id); + if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { if (baseClass.equals(Group.class)) { Context.getGroupsManager().refreshItems(); diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 41ed3e9d9..8467b46c6 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -44,7 +44,7 @@ public class ExtendedObjectResource extends BaseObjectResou var conditions = new LinkedList(); if (all) { - if (!permissionsService.isAdmin(getUserId())) { + if (permissionsService.notAdmin(getUserId())) { conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } } else { diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index 15a496c5f..4a435ca7d 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -41,7 +41,7 @@ public class SimpleObjectResource extends BaseObjectResourc var conditions = new LinkedList(); if (all) { - if (!permissionsService.isAdmin(getUserId())) { + if (permissionsService.notAdmin(getUserId())) { conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } } else { diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index 478b7acfd..fdd0d4f6f 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -67,10 +67,8 @@ public class AttributeResource extends ExtendedObjectResource { throw new IllegalArgumentException("Device has no last position"); } - Object result = new ComputedAttributesHandler( - Context.getConfig(), - Context.getIdentityManager(), - Context.getAttributesManager()).computeAttribute(entity, last); + Object result = new ComputedAttributesHandler(Context.getConfig(), Context.getIdentityManager(), null) + .computeAttribute(entity, last); if (result != null) { switch (entity.getType()) { case "number": diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 7def38919..484c61e66 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.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"); @@ -16,10 +16,11 @@ */ package org.traccar.api.resource; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Set; +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.helper.LogAction; +import org.traccar.model.Permission; +import org.traccar.storage.StorageException; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -29,34 +30,21 @@ import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.LogAction; -import org.traccar.model.Device; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; @Path("permissions") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class PermissionsResource extends BaseResource { - private void checkPermission(Permission permission, boolean link) { - if (!link && permission.getOwnerClass().equals(User.class) - && permission.getPropertyClass().equals(Device.class)) { - if (getUserId() != permission.getOwnerId()) { - Context.getPermissionsManager().checkUser(getUserId(), permission.getOwnerId()); - } else { - Context.getPermissionsManager().checkAdmin(getUserId()); - } - } else { - Context.getPermissionsManager().checkPermission( - permission.getOwnerClass(), getUserId(), permission.getOwnerId()); + private void checkPermission(Permission permission, boolean link) throws StorageException { + if (permissionsService.notAdmin(getUserId())) { + permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); + permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); } - Context.getPermissionsManager().checkPermission( - permission.getPropertyClass(), getUserId(), permission.getPropertyId()); } private void checkPermissionTypes(List> entities) { diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index ac687fc1c..9daef355e 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -61,8 +61,8 @@ public class PermissionsService { return user; } - public boolean isAdmin(long userId) throws StorageException { - return getUser(userId).getAdministrator(); + public boolean notAdmin(long userId) throws StorageException { + return !getUser(userId).getAdministrator(); } public void checkAdmin(long userId) throws StorageException, SecurityException { @@ -134,16 +134,11 @@ public class PermissionsService { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { var objects = storage.getObjects(clazz, new Request( new Columns.Include("id"), - new Condition.Permission( - User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz))); - boolean found = false; - for (var object : objects) { - if (object.getId() == objectId) { - found = true; - break; - } - } - if (!found) { + new Condition.And( + new Condition.Equals("id", "id", objectId), + new Condition.Permission( + User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz)))); + if (!objects.isEmpty()) { throw new SecurityException(clazz.getSimpleName() + " access denied"); } } diff --git a/src/main/java/org/traccar/database/AttributesManager.java b/src/main/java/org/traccar/database/AttributesManager.java deleted file mode 100644 index 28816645a..000000000 --- a/src/main/java/org/traccar/database/AttributesManager.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.database; - -import org.traccar.model.Attribute; - -public class AttributesManager extends ExtendedObjectManager { - - public AttributesManager(DataManager dataManager) { - super(dataManager, Attribute.class); - } - - @Override - public void updateCachedItem(Attribute attribute) { - Attribute cachedAttribute = getById(attribute.getId()); - cachedAttribute.setDescription(attribute.getDescription()); - cachedAttribute.setAttribute(attribute.getAttribute()); - cachedAttribute.setExpression(attribute.getExpression()); - cachedAttribute.setType(attribute.getType()); - } - -} diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 9ac808a69..b5966ca9e 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -240,8 +240,9 @@ public class DataManager { return storage.getPermissions(owner, property); } - public void linkObject(Class owner, long ownerId, Class property, long propertyId, boolean link) - throws StorageException { + public void linkObject( + Class owner, long ownerId, + Class property, long propertyId, boolean link) throws StorageException { if (link) { storage.addPermission(new Permission(owner, ownerId, property, propertyId)); } else { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 9a673c784..29bb8a27b 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -18,7 +18,6 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; @@ -368,26 +367,8 @@ public class PermissionsManager { if (object.equals(Device.class)) { checkDevice(userId, objectId); - } else if (object.equals(Group.class)) { - checkGroup(userId, objectId); - } else if (object.equals(User.class) || object.equals(ManagedUser.class)) { - checkUser(userId, objectId); - } else if (object.equals(Geofence.class)) { - manager = Context.getGeofenceManager(); - } else if (object.equals(Attribute.class)) { - manager = Context.getAttributesManager(); - } else if (object.equals(Driver.class)) { - manager = Context.getDriversManager(); - } else if (object.equals(Calendar.class)) { - manager = Context.getCalendarManager(); } else if (object.equals(Command.class)) { manager = Context.getCommandsManager(); - } else if (object.equals(Maintenance.class)) { - manager = Context.getMaintenancesManager(); - } else if (object.equals(Notification.class)) { - manager = Context.getNotificationManager(); - } else if (object.equals(Order.class)) { - manager = Context.getOrderManager(); } else { throw new IllegalArgumentException("Unknown object type"); } @@ -409,7 +390,6 @@ public class PermissionsManager { } Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); - Context.getAttributesManager().refreshUserItems(); Context.getCommandsManager().refreshUserItems(); Context.getMaintenancesManager().refreshUserItems(); if (Context.getNotificationManager() != null) { @@ -422,7 +402,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } Context.getDriversManager().refreshExtendedPermissions(); - Context.getAttributesManager().refreshExtendedPermissions(); Context.getCommandsManager().refreshExtendedPermissions(); Context.getMaintenancesManager().refreshExtendedPermissions(); } @@ -439,8 +418,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Attribute.class)) { - Context.getAttributesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Calendar.class)) { Context.getCalendarManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Command.class)) { @@ -458,8 +435,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Attribute.class)) { - Context.getAttributesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Command.class)) { Context.getCommandsManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 9dc170909..bec3d38e0 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -34,11 +34,11 @@ import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.AttributesManager; import org.traccar.database.IdentityManager; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -48,7 +48,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ComputedAttributesHandler.class); private final IdentityManager identityManager; - private final AttributesManager attributesManager; + private final CacheManager cacheManager; private final JexlEngine engine; @@ -56,9 +56,9 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Inject public ComputedAttributesHandler( - Config config, IdentityManager identityManager, AttributesManager attributesManager) { + Config config, IdentityManager identityManager, CacheManager cacheManager) { this.identityManager = identityManager; - this.attributesManager = attributesManager; + this.cacheManager = cacheManager; engine = new JexlEngine(); engine.setStrict(true); engine.setFunctions(Collections.singletonMap("math", Math.class)); @@ -107,8 +107,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - Collection attributes = attributesManager.getItems( - attributesManager.getAllDeviceItems(position.getDeviceId())); + Collection attributes = cacheManager.getDeviceObjects(position.getDeviceId(), Attribute.class); for (Attribute attribute : attributes) { if (attribute.getAttribute() != null) { Object result = null; diff --git a/src/main/java/org/traccar/model/Permission.java b/src/main/java/org/traccar/model/Permission.java index bace6b7d4..41dfa43e4 100644 --- a/src/main/java/org/traccar/model/Permission.java +++ b/src/main/java/org/traccar/model/Permission.java @@ -31,12 +31,12 @@ import org.traccar.storage.QueryIgnore; public class Permission { - private static final Map> CLASSES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + private static final Map> CLASSES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); static { try { for (Class clazz : ClassScanner.findSubclasses(BaseModel.class)) { - CLASSES.put(clazz.getSimpleName(), clazz); + CLASSES.put(clazz.getSimpleName(), (Class) clazz); } } catch (IOException | ReflectiveOperationException | URISyntaxException e) { throw new RuntimeException(e); @@ -45,9 +45,9 @@ public class Permission { private final LinkedHashMap data; - private final Class ownerClass; + private final Class ownerClass; private final long ownerId; - private final Class propertyClass; + private final Class propertyClass; private final long propertyId; public Permission(LinkedHashMap data) { @@ -61,7 +61,9 @@ public class Permission { propertyId = property.getValue(); } - public Permission(Class ownerClass, long ownerId, Class propertyClass, long propertyId) { + public Permission( + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) { this.ownerClass = ownerClass; this.ownerId = ownerId; this.propertyClass = propertyClass; @@ -105,7 +107,7 @@ public class Permission { @QueryIgnore @JsonIgnore - public Class getOwnerClass() { + public Class getOwnerClass() { return ownerClass; } @@ -117,7 +119,7 @@ public class Permission { @QueryIgnore @JsonIgnore - public Class getPropertyClass() { + public Class getPropertyClass() { return propertyClass; } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index e4e4f3294..91dd6b077 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.GroupedModel; @@ -116,7 +117,8 @@ public class DatabaseStorage extends Storage { @Override public List getPermissions( - Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException { + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) throws StorageException { StringBuilder query = new StringBuilder("SELECT * FROM "); query.append(Permission.getStorageName(ownerClass, propertyClass)); var conditions = new LinkedList(); diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 71e895428..f19897ff8 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import org.traccar.model.BaseModel; import org.traccar.model.Pair; import org.traccar.model.Permission; import org.traccar.storage.query.Request; @@ -54,7 +55,8 @@ public class MemoryStorage extends Storage { @Override public List getPermissions( - Class ownerClass, long ownerId, Class propertyClass, long propertyId) { + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) { return getPermissionsSet(ownerClass, propertyClass).stream() .filter(pair -> ownerId == 0 || pair.getFirst().equals(ownerId)) .filter(pair -> propertyId == 0 || pair.getSecond().equals(propertyId)) diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 22b5aaedc..62dba0165 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import org.traccar.model.BaseModel; import org.traccar.model.Permission; import org.traccar.storage.query.Request; @@ -31,24 +32,28 @@ public abstract class Storage { public abstract void removeObject(Class clazz, Request request) throws StorageException; public abstract List getPermissions( - Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException; + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) throws StorageException; public abstract void addPermission(Permission permission) throws StorageException; public abstract void removePermission(Permission permission) throws StorageException; public List getPermissions( - Class ownerClass, Class propertyClass) throws StorageException { + Class ownerClass, + Class propertyClass) throws StorageException { return getPermissions(ownerClass, 0, propertyClass, 0); } public List getPermissions( - Class ownerClass, long ownerId, Class propertyClass) throws StorageException { + Class ownerClass, long ownerId, + Class propertyClass) throws StorageException { return getPermissions(ownerClass, ownerId, propertyClass, 0); } public List getPermissions( - Class ownerClass, Class propertyClass, long propertyId) throws StorageException { + Class ownerClass, + Class propertyClass, long propertyId) throws StorageException { return getPermissions(ownerClass, 0, propertyClass, propertyId); } -- cgit v1.2.3 From ec76482c15094a7e04964c67d3011a7e8e1ad6a9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 06:33:02 -0700 Subject: Refactor commands manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 19 ++- src/main/java/org/traccar/Context.java | 12 -- src/main/java/org/traccar/MainModule.java | 6 + .../org/traccar/api/resource/CommandResource.java | 104 ++++++++++---- .../org/traccar/api/resource/PositionResource.java | 3 +- .../org/traccar/api/resource/ReportResource.java | 21 +-- .../traccar/api/security/PermissionsService.java | 12 +- .../java/org/traccar/database/CommandsManager.java | 149 +++++++-------------- .../java/org/traccar/database/DataManager.java | 13 +- .../org/traccar/database/PermissionsManager.java | 31 ----- src/main/java/org/traccar/model/Server.java | 6 +- src/main/java/org/traccar/model/User.java | 8 +- .../java/org/traccar/model/UserRestrictions.java | 23 ++++ .../traccar/protocol/OsmAndProtocolDecoder.java | 9 +- .../java/org/traccar/storage/DatabaseStorage.java | 16 +++ .../java/org/traccar/storage/query/Condition.java | 16 +++ src/test/java/org/traccar/BaseTest.java | 2 + 17 files changed, 241 insertions(+), 209 deletions(-) create mode 100644 src/main/java/org/traccar/model/UserRestrictions.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 71ef686fa..5b3f129de 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -15,7 +15,6 @@ */ package org.traccar; -import com.google.inject.Inject; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.config.Config; @@ -32,6 +31,7 @@ import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import org.traccar.storage.StorageException; +import javax.inject.Inject; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Collection; @@ -51,6 +51,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private ConnectionManager connectionManager; private StatisticsManager statisticsManager; private MediaManager mediaManager; + private CommandsManager commandsManager; public BaseProtocolDecoder(Protocol protocol) { this.protocol = protocol; @@ -96,6 +97,15 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.mediaManager = mediaManager; } + @Inject + public void setCommandsManager(CommandsManager commandsManager) { + this.commandsManager = commandsManager; + } + + public CommandsManager getCommandsManager() { + return commandsManager; + } + public String writeMediaFile(String uniqueId, ByteBuf buf, String extension) { return mediaManager.writeFile(uniqueId, buf, extension); } @@ -204,11 +214,8 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } protected void sendQueuedCommands(Channel channel, SocketAddress remoteAddress, long deviceId) { - CommandsManager commandsManager = Context.getCommandsManager(); - if (commandsManager != null) { - for (Command command : commandsManager.readQueuedCommands(deviceId)) { - protocol.sendDataCommand(channel, remoteAddress, command); - } + for (Command command : commandsManager.readQueuedCommands(deviceId)) { + protocol.sendDataCommand(channel, remoteAddress, command); } } diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 4eab36a89..6ee8344ce 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -25,7 +25,6 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; -import org.traccar.database.CommandsManager; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -45,7 +44,6 @@ import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -217,12 +215,6 @@ public final class Context { return driversManager; } - private static CommandsManager commandsManager; - - public static CommandsManager getCommandsManager() { - return commandsManager; - } - private static MaintenancesManager maintenancesManager; public static MaintenancesManager getMaintenancesManager() { @@ -337,8 +329,6 @@ public final class Context { driversManager = new DriversManager(dataManager); - commandsManager = new CommandsManager(dataManager, config.getBoolean(Keys.COMMANDS_QUEUEING)); - orderManager = new OrderManager(dataManager); } @@ -392,8 +382,6 @@ public final class Context { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { return (BaseObjectManager) driversManager; - } else if (clazz.equals(Command.class)) { - return (BaseObjectManager) commandsManager; } else if (clazz.equals(Maintenance.class)) { return (BaseObjectManager) maintenancesManager; } else if (clazz.equals(Notification.class)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f46312221..7b46656b3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -60,6 +60,7 @@ import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; import org.traccar.reports.model.TripsConfig; +import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; @@ -134,6 +135,11 @@ public class MainModule extends AbstractModule { return Context.getMaintenancesManager(); } + @Provides + public static SmsManager provideSmsManager() { + return Context.getSmsManager(); + } + @Singleton @Provides public static Geocoder provideGeocoder(Config config) { diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index a31345246..17bb150f6 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * @@ -17,16 +17,23 @@ */ package org.traccar.api.resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.BaseProtocol; import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; import org.traccar.database.CommandsManager; import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Position; import org.traccar.model.Typed; +import org.traccar.model.UserRestrictions; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -35,40 +42,61 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; @Path("commands") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class CommandResource extends ExtendedObjectResource { + private static final Logger LOGGER = LoggerFactory.getLogger(CommandResource.class); + + @Inject + private CommandsManager commandsManager; + public CommandResource() { super(Command.class); } + private BaseProtocol getDeviceProtocol(long deviceId) throws StorageException { + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions(deviceId))); + if (position != null) { + return Context.getServerManager().getProtocol(position.getProtocol()); + } else { + return null; + } + } + @GET @Path("send") - public Collection get(@QueryParam("deviceId") long deviceId) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - CommandsManager commandsManager = Context.getCommandsManager(); - Set result = new HashSet<>(commandsManager.getUserItems(getUserId())); - result.retainAll(commandsManager.getSupportedCommands(deviceId)); - return commandsManager.getItems(result); + public Collection get(@QueryParam("deviceId") long deviceId) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + BaseProtocol protocol = getDeviceProtocol(deviceId); + return get(false, 0, 0, deviceId).stream().filter(command -> { + String type = command.getType(); + if (protocol != null) { + return command.getTextChannel() && protocol.getSupportedTextCommands().contains(type) + || !command.getTextChannel() && protocol.getSupportedDataCommands().contains(type); + } else { + return type.equals(Command.TYPE_CUSTOM); + } + }).collect(Collectors.toList()); } @POST @Path("send") public Response send(Command entity) throws Exception { - Context.getPermissionsManager().checkReadonly(getUserId()); - long deviceId = entity.getDeviceId(); - long id = entity.getId(); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - if (id != 0) { - Context.getPermissionsManager().checkPermission(Command.class, getUserId(), id); - Context.getPermissionsManager().checkUserDeviceCommand(getUserId(), deviceId, id); - } else { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } - if (!Context.getCommandsManager().sendCommand(entity)) { + permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); + permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); + if (!commandsManager.sendCommand(entity)) { return Response.accepted(entity).build(); } return Response.ok(entity).build(); @@ -78,15 +106,33 @@ public class CommandResource extends ExtendedObjectResource { @Path("types") public Collection get( @QueryParam("deviceId") long deviceId, - @QueryParam("protocol") String protocol, - @QueryParam("textChannel") boolean textChannel) { + @QueryParam("textChannel") boolean textChannel) throws StorageException { if (deviceId != 0) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - return Context.getCommandsManager().getCommandTypes(deviceId, textChannel); - } else if (protocol != null) { - return Context.getCommandsManager().getCommandTypes(protocol, textChannel); + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + BaseProtocol protocol = getDeviceProtocol(deviceId); + if (protocol != null) { + if (textChannel) { + return protocol.getSupportedTextCommands().stream().map(Typed::new).collect(Collectors.toList()); + } else { + return protocol.getSupportedDataCommands().stream().map(Typed::new).collect(Collectors.toList()); + } + } else { + return Collections.singletonList(new Typed(Command.TYPE_CUSTOM)); + } } else { - return Context.getCommandsManager().getAllCommandTypes(); + List result = new ArrayList<>(); + Field[] fields = Command.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { + try { + result.add(new Typed(field.get(null).toString())); + } catch (IllegalArgumentException | IllegalAccessException error) { + LOGGER.warn("Get command types error", error); + } + } + } + return result; } } + } diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 941417231..2618a04cb 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Position; +import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import javax.ws.rs.Consumes; @@ -55,7 +56,7 @@ public class PositionResource extends BaseResource { } else { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); if (from != null && to != null) { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return Context.getDataManager().getPositions(deviceId, from, to); } else { return Collections.singleton(Context.getDeviceManager().getLastPosition(deviceId)); diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 901385d0d..06ccbe4fd 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -42,6 +42,7 @@ import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.UserRestrictions; import org.traccar.reports.Events; import org.traccar.reports.Summary; import org.traccar.reports.Trips; @@ -99,7 +100,7 @@ public class ReportResource extends BaseResource { public Collection getRoute( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -111,7 +112,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -124,7 +125,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); } @@ -137,7 +138,7 @@ public class ReportResource extends BaseResource { @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); @@ -150,7 +151,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); } @@ -163,7 +164,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); @@ -176,7 +177,7 @@ public class ReportResource extends BaseResource { public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -188,7 +189,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -201,7 +202,7 @@ public class ReportResource extends BaseResource { public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -213,7 +214,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); Stops.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 9daef355e..b4a375109 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -25,6 +25,7 @@ import org.traccar.model.ManagedUser; import org.traccar.model.ScheduledModel; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.model.UserRestrictions; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -71,10 +72,15 @@ public class PermissionsService { } } - public void checkReports(long userId) throws StorageException, SecurityException { + public interface CheckRestrictionCallback { + boolean denied(UserRestrictions userRestrictions); + } + + public void checkRestriction( + long userId, CheckRestrictionCallback callback) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() - && (getServer().getDisableReports() || getUser(userId).getDisableReports())) { - throw new SecurityException("Reports are disabled"); + && (callback.denied(getServer()) || callback.denied(getUser(userId)))) { + throw new SecurityException("Operation restricted"); } } diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 57ce0f9a4..d440755f7 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -16,66 +16,75 @@ */ package org.traccar.database; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; +import org.traccar.BaseProtocol; +import org.traccar.ServerManager; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; +import org.traccar.session.DeviceSession; +import org.traccar.sms.SmsManager; +import org.traccar.storage.Storage; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseProtocol; -import org.traccar.Context; -import org.traccar.model.Command; -import org.traccar.model.Typed; -import org.traccar.model.Position; -import org.traccar.session.DeviceSession; - -public class CommandsManager extends ExtendedObjectManager { +@Singleton +public class CommandsManager { - private static final Logger LOGGER = LoggerFactory.getLogger(CommandsManager.class); + private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map> deviceQueues = new ConcurrentHashMap<>(); - private final boolean queueing; + private final Storage storage; + private final ServerManager serverManager; + private final SmsManager smsManager; + private final ConnectionManager connectionManager; - public CommandsManager(DataManager dataManager, boolean queueing) { - super(dataManager, Command.class); - this.queueing = queueing; - } + private final boolean queueing; - public boolean checkDeviceCommand(long deviceId, long commandId) { - return !getAllDeviceItems(deviceId).contains(commandId); + @Inject + public CommandsManager( + Storage storage, ServerManager serverManager, @Nullable SmsManager smsManager, + ConnectionManager connectionManager, Config config) { + this.storage = storage; + this.serverManager = serverManager; + this.smsManager = smsManager; + this.connectionManager = connectionManager; + queueing = config.getBoolean(Keys.COMMANDS_QUEUEING); } public boolean sendCommand(Command command) throws Exception { long deviceId = command.getDeviceId(); - if (command.getId() != 0) { - command = getById(command.getId()).clone(); - command.setDeviceId(deviceId); - } if (command.getTextChannel()) { - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - String phone = Context.getIdentityManager().getById(deviceId).getPhone(); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(phone, command); + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getPositionId()))); + if (position != null) { + BaseProtocol protocol = serverManager.getProtocol(position.getProtocol()); + protocol.sendTextCommand(device.getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - if (Context.getSmsManager() != null) { - Context.getSmsManager().sendMessageSync(phone, command.getString(Command.KEY_DATA), true); - } else { - throw new RuntimeException("SMS is not enabled"); - } + smsManager.sendMessageSync(device.getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); } } else { - DeviceSession deviceSession = Context.getConnectionManager().getDeviceSession(deviceId); + DeviceSession deviceSession = connectionManager.getDeviceSession(deviceId); if (deviceSession != null) { if (deviceSession.supportsLiveCommands()) { deviceSession.sendCommand(command); @@ -93,76 +102,22 @@ public class CommandsManager extends ExtendedObjectManager { return true; } - public Collection getSupportedCommands(long deviceId) { - List result = new ArrayList<>(); - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - for (long commandId : getAllDeviceItems(deviceId)) { - Command command = getById(commandId); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - if (command.getTextChannel() && protocol.getSupportedTextCommands().contains(command.getType()) - || !command.getTextChannel() - && protocol.getSupportedDataCommands().contains(command.getType())) { - result.add(commandId); - } - } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - result.add(commandId); - } - } - return result; - } - - public Collection getCommandTypes(long deviceId, boolean textChannel) { - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - if (lastPosition != null) { - return getCommandTypes(lastPosition.getProtocol(), textChannel); - } else { - return Collections.singletonList(new Typed(Command.TYPE_CUSTOM)); - } - } - - public Collection getCommandTypes(String protocolName, boolean textChannel) { - List result = new ArrayList<>(); - BaseProtocol protocol = Context.getServerManager().getProtocol(protocolName); - Collection commands; - commands = textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands(); - for (String commandKey : commands) { - result.add(new Typed(commandKey)); - } - return result; - } - - public Collection getAllCommandTypes() { - List result = new ArrayList<>(); - Field[] fields = Command.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { - try { - result.add(new Typed(field.get(null).toString())); - } catch (IllegalArgumentException | IllegalAccessException error) { - LOGGER.warn("Get command types error", error); - } - } - } - return result; - } - private Queue getDeviceQueue(long deviceId) { Queue deviceQueue; try { - readLock(); + lock.readLock().lock(); deviceQueue = deviceQueues.get(deviceId); } finally { - readUnlock(); + lock.readLock().unlock(); } if (deviceQueue != null) { return deviceQueue; } else { try { - writeLock(); + lock.writeLock().lock(); return deviceQueues.computeIfAbsent(deviceId, key -> new ConcurrentLinkedQueue<>()); } finally { - writeUnlock(); + lock.writeLock().unlock(); } } } @@ -174,10 +129,10 @@ public class CommandsManager extends ExtendedObjectManager { public Collection readQueuedCommands(long deviceId, int count) { Queue deviceQueue; try { - readLock(); + lock.readLock().lock(); deviceQueue = deviceQueues.get(deviceId); } finally { - readUnlock(); + lock.readLock().unlock(); } Collection result = new ArrayList<>(); if (deviceQueue != null) { diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index b5966ca9e..1426daea3 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -50,8 +50,6 @@ import java.lang.reflect.Method; import java.net.URL; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; public class DataManager { @@ -205,14 +203,9 @@ public class DataManager { } public Collection getLatestPositions() throws StorageException { - List positions = new LinkedList<>(); - List devices = storage.getObjects(Device.class, new Request(new Columns.Include("positionId"))); - for (Device device : devices) { - positions.addAll(storage.getObjects(Position.class, new Request( - new Columns.All(), - new Condition.Equals("id", "id", device.getPositionId())))); - } - return positions; + return storage.getObjects(Position.class, new Request( + new Columns.All(), + new Condition.LatestPositions())); } public Server getServer() throws StorageException { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 29bb8a27b..4d5c59fcc 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -274,18 +273,6 @@ public class PermissionsManager { } } - public void checkLimitCommands(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getLimitCommands() || getUserLimitCommands(userId))) { - throw new SecurityException("Account has limit sending commands"); - } - } - - public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException { - if (!getUserAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) { - throw new SecurityException("Command can not be sent to this device"); - } - } - public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); if (user == null) { @@ -367,21 +354,9 @@ public class PermissionsManager { if (object.equals(Device.class)) { checkDevice(userId, objectId); - } else if (object.equals(Command.class)) { - manager = Context.getCommandsManager(); } else { throw new IllegalArgumentException("Unknown object type"); } - - if (manager != null && !manager.checkItemPermission(userId, objectId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getManagedItems(userId)) { - if (manager.checkItemPermission(managedUserId, objectId)) { - return; - } - } - throw new SecurityException("Type " + object + " access denied"); - } } public void refreshAllUsersPermissions() { @@ -390,7 +365,6 @@ public class PermissionsManager { } Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); - Context.getCommandsManager().refreshUserItems(); Context.getMaintenancesManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -402,7 +376,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } Context.getDriversManager().refreshExtendedPermissions(); - Context.getCommandsManager().refreshExtendedPermissions(); Context.getMaintenancesManager().refreshExtendedPermissions(); } @@ -420,8 +393,6 @@ public class PermissionsManager { Context.getDriversManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Calendar.class)) { Context.getCalendarManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Command.class)) { - Context.getCommandsManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Order.class)) { @@ -435,8 +406,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Command.class)) { - Context.getCommandsManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Order.class)) { diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index b48e84939..7cffd7eac 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -22,7 +22,7 @@ import org.traccar.storage.StorageName; @StorageName("tc_servers") @JsonIgnoreProperties(ignoreUnknown = true) -public class Server extends ExtendedModel { +public class Server extends ExtendedModel implements UserRestrictions { private boolean registration; @@ -36,6 +36,7 @@ public class Server extends ExtendedModel { private boolean readonly; + @Override public boolean getReadonly() { return readonly; } @@ -46,6 +47,7 @@ public class Server extends ExtendedModel { private boolean deviceReadonly; + @Override public boolean getDeviceReadonly() { return deviceReadonly; } @@ -146,6 +148,7 @@ public class Server extends ExtendedModel { private boolean limitCommands; + @Override public boolean getLimitCommands() { return limitCommands; } @@ -156,6 +159,7 @@ public class Server extends ExtendedModel { private boolean disableReports; + @Override public boolean getDisableReports() { return disableReports; } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 6a67f3276..12fd03d45 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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,7 +25,7 @@ import org.traccar.storage.StorageName; import java.util.Date; @StorageName("tc_users") -public class User extends ExtendedModel { +public class User extends ExtendedModel implements UserRestrictions { private String name; @@ -69,6 +69,7 @@ public class User extends ExtendedModel { private boolean readonly; + @Override public boolean getReadonly() { return readonly; } @@ -195,6 +196,7 @@ public class User extends ExtendedModel { private boolean deviceReadonly; + @Override public boolean getDeviceReadonly() { return deviceReadonly; } @@ -222,6 +224,7 @@ public class User extends ExtendedModel { private boolean limitCommands; + @Override public boolean getLimitCommands() { return limitCommands; } @@ -234,6 +237,7 @@ public class User extends ExtendedModel { private boolean disableReports; + @Override public boolean getDisableReports() { return disableReports; } diff --git a/src/main/java/org/traccar/model/UserRestrictions.java b/src/main/java/org/traccar/model/UserRestrictions.java new file mode 100644 index 000000000..2e4e5e363 --- /dev/null +++ b/src/main/java/org/traccar/model/UserRestrictions.java @@ -0,0 +1,23 @@ +/* + * 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.model; + +public interface UserRestrictions { + boolean getReadonly(); + boolean getDeviceReadonly(); + boolean getLimitCommands(); + boolean getDisableReports(); +} diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index 178ec344f..3574dd2a3 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -21,10 +21,8 @@ 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.Context; import org.traccar.session.DeviceSession; import org.traccar.Protocol; -import org.traccar.database.CommandsManager; import org.traccar.helper.DateUtil; import org.traccar.model.CellTower; import org.traccar.model.Command; @@ -178,11 +176,8 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { if (position.getDeviceId() != 0) { String response = null; - CommandsManager commandsManager = Context.getCommandsManager(); - if (commandsManager != null) { - for (Command command : commandsManager.readQueuedCommands(position.getDeviceId(), 1)) { - response = command.getString(Command.KEY_DATA); - } + for (Command command : getCommandsManager().readQueuedCommands(position.getDeviceId(), 1)) { + response = command.getString(Command.KEY_DATA); } if (response != null) { sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(response, StandardCharsets.UTF_8)); diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 91dd6b077..fc468182e 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -209,6 +209,11 @@ public class DatabaseStorage extends Storage { } else { results.put(Permission.getKey(condition.getPropertyClass()), condition.getPropertyId()); } + } else if (genericCondition instanceof Condition.LatestPositions) { + var condition = (Condition.LatestPositions) genericCondition; + if (condition.getDeviceId() > 0) { + results.put("deviceId", condition.getDeviceId()); + } } return results; } @@ -262,6 +267,17 @@ public class DatabaseStorage extends Storage { result.append(formatPermissionQuery(condition)); result.append(")"); + } else if (genericCondition instanceof Condition.LatestPositions) { + + var condition = (Condition.LatestPositions) genericCondition; + result.append("id IN ("); + result.append("SELECT positionId FROM "); + result.append(getStorageName(Device.class)); + if (condition.getDeviceId() > 0) { + result.append(" WHERE id = :deviceId"); + } + result.append(")"); + } } return result.toString(); diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 91ede236c..136b0402b 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -196,4 +196,20 @@ public interface Condition { } } + class LatestPositions implements Condition { + private final long deviceId; + + public LatestPositions(long deviceId) { + this.deviceId = deviceId; + } + + public LatestPositions() { + this(0); + } + + public long getDeviceId() { + return deviceId; + } + } + } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index a34524c43..1652a6694 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -2,6 +2,7 @@ package org.traccar; import io.netty.channel.Channel; import org.traccar.config.Config; +import org.traccar.database.CommandsManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; @@ -52,6 +53,7 @@ public class BaseTest { decoder.setConnectionManager(connectionManager); decoder.setStatisticsManager(mock(StatisticsManager.class)); decoder.setMediaManager(mock(MediaManager.class)); + decoder.setCommandsManager(mock(CommandsManager.class)); return decoder; } -- cgit v1.2.3 From ea22ffb859f8bb8fa0a468af192fef395653d645 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 06:50:50 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 16 ---------------- src/main/java/org/traccar/Main.java | 5 +++-- src/main/java/org/traccar/ServerManager.java | 2 ++ .../java/org/traccar/api/resource/CommandResource.java | 7 +++++-- src/main/java/org/traccar/schedule/ScheduleManager.java | 2 ++ .../java/org/traccar/session/cache/CacheManager.java | 3 +-- 6 files changed, 13 insertions(+), 22 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 6ee8344ce..eaf973659 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -55,7 +55,6 @@ import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.reports.model.TripsConfig; -import org.traccar.schedule.ScheduleManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -149,18 +148,6 @@ public final class Context { return webServer; } - private static ServerManager serverManager; - - public static ServerManager getServerManager() { - return serverManager; - } - - private static ScheduleManager scheduleManager; - - public static ScheduleManager getScheduleManager() { - return scheduleManager; - } - private static BroadcastService broadcastService; public static BroadcastService getBroadcastService() { @@ -316,9 +303,6 @@ public final class Context { initEventsModule(); - serverManager = new ServerManager(); - scheduleManager = new ScheduleManager(); - if (config.hasKey(Keys.BROADCAST_ADDRESS)) { broadcastService = new BroadcastService(config, objectMapper); } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 016365837..db9892bb9 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -19,6 +19,7 @@ import com.google.inject.Guice; import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.schedule.ScheduleManager; import java.io.File; import java.lang.management.ManagementFactory; @@ -117,9 +118,9 @@ public final class Main { LOGGER.info("Starting server..."); List services = new LinkedList<>(); - services.add(Context.getServerManager()); + services.add(injector.getInstance(ServerManager.class)); services.add(Context.getWebServer()); - services.add(Context.getScheduleManager()); + services.add(injector.getInstance(ScheduleManager.class)); services.add(Context.getBroadcastService()); for (LifecycleObject service : services) { diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 15faf9f2b..a6bb6888c 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Keys; import org.traccar.helper.ClassScanner; +import javax.inject.Singleton; import java.io.IOException; import java.net.BindException; import java.net.ConnectException; @@ -29,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +@Singleton public class ServerManager implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 17bb150f6..60f1f8eb0 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -20,7 +20,7 @@ package org.traccar.api.resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocol; -import org.traccar.Context; +import org.traccar.ServerManager; import org.traccar.api.ExtendedObjectResource; import org.traccar.database.CommandsManager; import org.traccar.model.Command; @@ -60,6 +60,9 @@ public class CommandResource extends ExtendedObjectResource { @Inject private CommandsManager commandsManager; + @Inject + private ServerManager serverManager; + public CommandResource() { super(Command.class); } @@ -68,7 +71,7 @@ public class CommandResource extends ExtendedObjectResource { Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.LatestPositions(deviceId))); if (position != null) { - return Context.getServerManager().getProtocol(position.getProtocol()); + return serverManager.getProtocol(position.getProtocol()); } else { return null; } diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 7a3d33b85..154de603a 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -17,9 +17,11 @@ package org.traccar.schedule; import org.traccar.LifecycleObject; +import javax.inject.Singleton; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +@Singleton public class ScheduleManager implements LifecycleObject { private ScheduledExecutorService executor; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 4669024d3..f2570f77c 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -50,8 +50,7 @@ import java.util.stream.Collectors; public class CacheManager { private static final Collection> CLASSES = Arrays.asList( - Attribute.class, Command.class, Driver.class, Geofence.class, - Maintenance.class, Notification.class, Order.class); + Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); private final Storage storage; -- cgit v1.2.3 From 89b317968655904749addb96b08dfd4681631331 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 06:53:17 -0700 Subject: Remove order manager --- src/main/java/org/traccar/Context.java | 12 ---------- .../java/org/traccar/database/OrderManager.java | 26 ---------------------- .../org/traccar/database/PermissionsManager.java | 5 ----- .../org/traccar/session/cache/CacheManager.java | 2 -- 4 files changed, 45 deletions(-) delete mode 100644 src/main/java/org/traccar/database/OrderManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index eaf973659..97cfb2bf9 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -36,7 +36,6 @@ import org.traccar.database.LdapProvider; import org.traccar.database.MailManager; import org.traccar.database.MaintenancesManager; import org.traccar.database.NotificationManager; -import org.traccar.database.OrderManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; import org.traccar.geocoder.Geocoder; @@ -50,7 +49,6 @@ import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.model.Notification; -import org.traccar.model.Order; import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; @@ -208,12 +206,6 @@ public final class Context { return maintenancesManager; } - private static OrderManager orderManager; - - public static OrderManager getOrderManager() { - return orderManager; - } - private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -313,8 +305,6 @@ public final class Context { driversManager = new DriversManager(dataManager); - orderManager = new OrderManager(dataManager); - } private static void initEventsModule() { @@ -370,8 +360,6 @@ public final class Context { return (BaseObjectManager) maintenancesManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; - } else if (clazz.equals(Order.class)) { - return (BaseObjectManager) orderManager; } return null; } diff --git a/src/main/java/org/traccar/database/OrderManager.java b/src/main/java/org/traccar/database/OrderManager.java deleted file mode 100644 index c3253e52f..000000000 --- a/src/main/java/org/traccar/database/OrderManager.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 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. - * 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.database; - -import org.traccar.model.Order; - -public class OrderManager extends ExtendedObjectManager { - - public OrderManager(DataManager dataManager) { - super(dataManager, Order.class); - } - -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 4d5c59fcc..46e19d380 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -27,7 +27,6 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; -import org.traccar.model.Order; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; @@ -395,8 +394,6 @@ public class PermissionsManager { Context.getCalendarManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Order.class)) { - Context.getOrderManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -408,8 +405,6 @@ public class PermissionsManager { Context.getDriversManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Order.class)) { - Context.getOrderManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index f2570f77c..aca3df52d 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -17,13 +17,11 @@ package org.traccar.session.cache; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Notification; -import org.traccar.model.Order; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.storage.Storage; -- cgit v1.2.3 From fd84b0dcb86208c2c9c64fbe067cf7d4324892ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 09:59:13 -0700 Subject: Remove ldap from context --- src/main/java/org/traccar/Context.java | 13 +------------ src/main/java/org/traccar/MainModule.java | 12 +++++++++++- src/main/java/org/traccar/database/DataManager.java | 13 +++++++------ src/main/java/org/traccar/database/LdapProvider.java | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 97cfb2bf9..1aa673077 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -25,14 +25,12 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; -import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; -import org.traccar.database.LdapProvider; import org.traccar.database.MailManager; import org.traccar.database.MaintenancesManager; import org.traccar.database.NotificationManager; @@ -53,6 +51,7 @@ import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.reports.model.TripsConfig; +import org.traccar.session.ConnectionManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -94,12 +93,6 @@ public final class Context { return dataManager; } - private static LdapProvider ldapProvider; - - public static LdapProvider getLdapProvider() { - return ldapProvider; - } - private static MailManager mailManager; public static MailManager getMailManager() { @@ -263,10 +256,6 @@ public final class Context { dataManager = new DataManager(config); } - if (config.hasKey(Keys.LDAP_URL)) { - ldapProvider = new LdapProvider(config); - } - mailManager = new MailManager(); if (dataManager != null) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 7b46656b3..15b9cefda 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -19,12 +19,12 @@ 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.CalendarManager; +import org.traccar.database.LdapProvider; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -66,6 +66,7 @@ import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; import javax.annotation.Nullable; +import javax.inject.Singleton; import javax.ws.rs.client.Client; public class MainModule extends AbstractModule { @@ -140,6 +141,15 @@ public class MainModule extends AbstractModule { return Context.getSmsManager(); } + @Singleton + @Provides + public static LdapProvider provideLdapProvider(Config config) { + if (config.hasKey(Keys.LDAP_URL)) { + return new LdapProvider(config); + } + return null; + } + @Singleton @Provides public static Geocoder provideGeocoder(Config config) { diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 1426daea3..29d70ec32 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -25,6 +25,7 @@ import liquibase.exception.LiquibaseException; import liquibase.resource.FileSystemResourceAccessor; import liquibase.resource.ResourceAccessor; import org.traccar.Context; +import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.BaseModel; @@ -131,12 +132,12 @@ public class DataManager { config.getString(Keys.DATABASE_DRIVER), null, null, null, resourceAccessor); - Liquibase liquibase = new Liquibase( - config.getString(Keys.DATABASE_CHANGELOG), resourceAccessor, database); + String changelog = config.getString(Keys.DATABASE_CHANGELOG); - liquibase.clearCheckSums(); - - liquibase.update(new Contexts()); + try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { + liquibase.clearCheckSums(); + liquibase.update(new Contexts()); + } } } @@ -146,7 +147,7 @@ public class DataManager { new Condition.Or( new Condition.Equals("email", "email", email.trim()), new Condition.Equals("login", "email")))); - LdapProvider ldapProvider = Context.getLdapProvider(); + LdapProvider ldapProvider = Main.getInjector().getInstance(LdapProvider.class); if (user != null) { if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) || !forceLdap && user.isPasswordValid(password)) { diff --git a/src/main/java/org/traccar/database/LdapProvider.java b/src/main/java/org/traccar/database/LdapProvider.java index d659a11a1..d517294b8 100644 --- a/src/main/java/org/traccar/database/LdapProvider.java +++ b/src/main/java/org/traccar/database/LdapProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 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. -- cgit v1.2.3 From 8c12ded81c5dce295fcb229c566209d784f55356 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 10:38:49 -0700 Subject: Remove maintenance manager --- src/main/java/org/traccar/Context.java | 13 +---- src/main/java/org/traccar/MainModule.java | 6 --- .../org/traccar/api/resource/ReportResource.java | 4 +- .../traccar/api/security/PermissionsService.java | 4 +- .../org/traccar/database/MaintenancesManager.java | 27 ---------- .../org/traccar/database/NotificationManager.java | 57 ++++++++++------------ .../org/traccar/database/PermissionsManager.java | 7 --- .../handler/events/MaintenanceEventHandler.java | 25 +++------- .../org/traccar/notification/EventForwarder.java | 20 +++++--- .../notification/NotificationFormatter.java | 21 ++++---- .../traccar/notificators/NotificatorFirebase.java | 5 +- .../org/traccar/notificators/NotificatorMail.java | 5 +- .../traccar/notificators/NotificatorPushover.java | 5 +- .../org/traccar/notificators/NotificatorSms.java | 7 ++- .../traccar/notificators/NotificatorTelegram.java | 5 +- src/main/java/org/traccar/reports/Events.java | 34 +++++++------ src/main/java/org/traccar/reports/ReportUtils.java | 16 ++++++ 17 files changed, 117 insertions(+), 144 deletions(-) delete mode 100644 src/main/java/org/traccar/database/MaintenancesManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 1aa673077..a833d0c52 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -32,7 +32,6 @@ import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.MailManager; -import org.traccar.database.MaintenancesManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; @@ -45,7 +44,6 @@ import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; -import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.User; import org.traccar.notification.EventForwarder; @@ -193,12 +191,6 @@ public final class Context { return driversManager; } - private static MaintenancesManager maintenancesManager; - - public static MaintenancesManager getMaintenancesManager() { - return maintenancesManager; - } - private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -289,7 +281,7 @@ public final class Context { } if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - eventForwarder = new EventForwarder(); + eventForwarder = new EventForwarder(config); } driversManager = new DriversManager(dataManager); @@ -300,7 +292,6 @@ public final class Context { geofenceManager = new GeofenceManager(dataManager); calendarManager = new CalendarManager(dataManager); - maintenancesManager = new MaintenancesManager(dataManager); notificationManager = new NotificationManager(dataManager); notificatorManager = new NotificatorManager(); Properties velocityProperties = new Properties(); @@ -345,8 +336,6 @@ public final class Context { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { return (BaseObjectManager) driversManager; - } else if (clazz.equals(Maintenance.class)) { - return (BaseObjectManager) maintenancesManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 15b9cefda..219a8fc11 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,7 +30,6 @@ import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; -import org.traccar.database.MaintenancesManager; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; @@ -131,11 +130,6 @@ public class MainModule extends AbstractModule { return Context.getCalendarManager(); } - @Provides - public static MaintenancesManager provideMaintenancesManager() { - return Context.getMaintenancesManager(); - } - @Provides public static SmsManager provideSmsManager() { return Context.getSmsManager(); diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 06ccbe4fd..a7bbe1067 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -127,7 +127,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); + return Events.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); } @Path("events") @@ -141,7 +141,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); + Events.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); }); } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index b4a375109..12a2189e9 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -138,13 +138,13 @@ public class PermissionsService { public void checkPermission( Class clazz, long userId, long objectId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { - var objects = storage.getObjects(clazz, new Request( + var object = storage.getObject(clazz, new Request( new Columns.Include("id"), new Condition.And( new Condition.Equals("id", "id", objectId), new Condition.Permission( User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz)))); - if (!objects.isEmpty()) { + if (object == null) { throw new SecurityException(clazz.getSimpleName() + " access denied"); } } diff --git a/src/main/java/org/traccar/database/MaintenancesManager.java b/src/main/java/org/traccar/database/MaintenancesManager.java deleted file mode 100644 index 4e266cb78..000000000 --- a/src/main/java/org/traccar/database/MaintenancesManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2018 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.database; - -import org.traccar.model.Maintenance; - -public class MaintenancesManager extends ExtendedObjectManager { - - public MaintenancesManager(DataManager dataManager) { - super(dataManager, Maintenance.class); - } - -} diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index f358b1d4d..64f3b6775 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -77,42 +77,37 @@ public class NotificationManager extends ExtendedObjectManager { usersToForward = new HashSet<>(); } for (long userId : users) { - if ((event.getGeofenceId() == 0 - || Context.getGeofenceManager().checkItemPermission(userId, event.getGeofenceId())) - && (event.getMaintenanceId() == 0 - || Context.getMaintenancesManager().checkItemPermission(userId, event.getMaintenanceId()))) { - if (usersToForward != null) { - usersToForward.add(userId); - } - final Set notificators = new HashSet<>(); - for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { - Notification notification = getById(notificationId); - if (getById(notificationId).getType().equals(event.getType())) { - boolean filter = false; - if (event.getType().equals(Event.TYPE_ALARM)) { - String alarmsAttribute = notification.getString("alarms"); - if (alarmsAttribute == null) { - filter = true; - } else { - List alarms = Arrays.asList(alarmsAttribute.split(",")); - filter = !alarms.contains(event.getString(Position.KEY_ALARM)); - } - } - if (!filter) { - notificators.addAll(notification.getNotificatorsTypes()); + if (usersToForward != null) { + usersToForward.add(userId); + } + final Set notificators = new HashSet<>(); + for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { + Notification notification = getById(notificationId); + if (getById(notificationId).getType().equals(event.getType())) { + boolean filter = false; + if (event.getType().equals(Event.TYPE_ALARM)) { + String alarmsAttribute = notification.getString("alarms"); + if (alarmsAttribute == null) { + filter = true; + } else { + List alarms = Arrays.asList(alarmsAttribute.split(",")); + filter = !alarms.contains(event.getString(Position.KEY_ALARM)); } } + if (!filter) { + notificators.addAll(notification.getNotificatorsTypes()); + } } + } - if (position != null && position.getAddress() == null - && geocodeOnRequest && Context.getGeocoder() != null) { - position.setAddress(Context.getGeocoder() - .getAddress(position.getLatitude(), position.getLongitude(), null)); - } + if (position != null && position.getAddress() == null + && geocodeOnRequest && Context.getGeocoder() != null) { + position.setAddress(Context.getGeocoder() + .getAddress(position.getLatitude(), position.getLongitude(), null)); + } - for (String notificator : notificators) { - Context.getNotificatorManager().getNotificator(notificator).sendAsync(userId, event, position); - } + for (String notificator : notificators) { + Context.getNotificatorManager().getNotificator(notificator).sendAsync(userId, event, position); } } if (Context.getEventForwarder() != null) { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 46e19d380..61b35b380 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -24,7 +24,6 @@ import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; -import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; import org.traccar.model.Permission; @@ -364,7 +363,6 @@ public class PermissionsManager { } Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); - Context.getMaintenancesManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } @@ -375,7 +373,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } Context.getDriversManager().refreshExtendedPermissions(); - Context.getMaintenancesManager().refreshExtendedPermissions(); } public void refreshPermissions(Permission permission) { @@ -392,8 +389,6 @@ public class PermissionsManager { Context.getDriversManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Calendar.class)) { Context.getCalendarManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Maintenance.class)) { - Context.getMaintenancesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -403,8 +398,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Maintenance.class)) { - Context.getMaintenancesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 5b9ce4316..be3e9bf8d 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -20,41 +20,32 @@ import java.util.HashMap; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; -import org.traccar.database.MaintenancesManager; import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class MaintenanceEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; - private final MaintenancesManager maintenancesManager; + private final CacheManager cacheManager; @Inject - public MaintenanceEventHandler(IdentityManager identityManager, MaintenancesManager maintenancesManager) { - this.identityManager = identityManager; - this.maintenancesManager = maintenancesManager; + public MaintenanceEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - if (identityManager.getById(position.getDeviceId()) == null - || !identityManager.isLatestPosition(position)) { - return null; - } - - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (lastPosition == null) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) < 0) { return null; } Map events = new HashMap<>(); - for (long maintenanceId : maintenancesManager.getAllDeviceItems(position.getDeviceId())) { - Maintenance maintenance = maintenancesManager.getById(maintenanceId); + for (Maintenance maintenance : cacheManager.getDeviceObjects(position.getDeviceId(), Maintenance.class)) { if (maintenance.getPeriod() != 0) { double oldValue = lastPosition.getDouble(maintenance.getType()); double newValue = position.getDouble(maintenance.getType()); @@ -62,7 +53,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { && (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { Event event = new Event(Event.TYPE_MAINTENANCE, position); - event.setMaintenanceId(maintenanceId); + event.setMaintenanceId(maintenance.getId()); event.set(maintenance.getType(), newValue); events.put(event, position); } diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index c908fedbd..b0494d74d 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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. @@ -18,12 +18,15 @@ package org.traccar.notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; @@ -39,9 +42,12 @@ public class EventForwarder { private final String url; private final String header; - public EventForwarder() { - url = Context.getConfig().getString(Keys.EVENT_FORWARD_URL); - header = Context.getConfig().getString(Keys.EVENT_FORWARD_HEADERS); + private final CacheManager cacheManager; + + public EventForwarder(Config config) { + url = config.getString(Keys.EVENT_FORWARD_URL); + header = config.getString(Keys.EVENT_FORWARD_HEADERS); + cacheManager = Main.getInjector().getInstance(CacheManager.class); } private static final String KEY_POSITION = "position"; @@ -83,18 +89,18 @@ public class EventForwarder { if (position != null) { data.put(KEY_POSITION, position); } - Device device = Context.getIdentityManager().getById(event.getDeviceId()); + Device device = cacheManager.getObject(Device.class, event.getDeviceId()); if (device != null) { data.put(KEY_DEVICE, device); } if (event.getGeofenceId() != 0) { - Geofence geofence = Context.getGeofenceManager().getById(event.getGeofenceId()); + Geofence geofence = cacheManager.getObject(Geofence.class, event.getGeofenceId()); if (geofence != null) { data.put(KEY_GEOFENCE, geofence); } } if (event.getMaintenanceId() != 0) { - Maintenance maintenance = Context.getMaintenancesManager().getById(event.getMaintenanceId()); + Maintenance maintenance = cacheManager.getObject(Maintenance.class, event.getMaintenanceId()); if (maintenance != null) { data.put(KEY_MAINTENANCE, maintenance); } diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 9a6723a71..107426e06 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,19 +20,23 @@ import org.apache.velocity.VelocityContext; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.reports.ReportUtils; +import org.traccar.session.cache.CacheManager; public final class NotificationFormatter { private NotificationFormatter() { } - public static VelocityContext prepareContext(long userId, Event event, Position position) { + public static NotificationMessage formatMessage( + CacheManager cacheManager, long userId, Event event, Position position, String templatePath) { - User user = Context.getPermissionsManager().getUser(userId); - Device device = Context.getIdentityManager().getById(event.getDeviceId()); + User user = cacheManager.getObject(User.class, userId); + Device device = cacheManager.getObject(Device.class, event.getDeviceId()); VelocityContext velocityContext = TextTemplateFormatter.prepareContext(user); @@ -45,21 +49,16 @@ public final class NotificationFormatter { velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(userId)); } if (event.getGeofenceId() != 0) { - velocityContext.put("geofence", Context.getGeofenceManager().getById(event.getGeofenceId())); + velocityContext.put("geofence", cacheManager.getObject(Geofence.class, event.getGeofenceId())); } if (event.getMaintenanceId() != 0) { - velocityContext.put("maintenance", Context.getMaintenancesManager().getById(event.getMaintenanceId())); + velocityContext.put("maintenance", cacheManager.getObject(Maintenance.class, event.getMaintenanceId())); } String driverUniqueId = event.getString(Position.KEY_DRIVER_UNIQUE_ID); if (driverUniqueId != null) { velocityContext.put("driver", Context.getDriversManager().getDriverByUniqueId(driverUniqueId)); } - return velocityContext; - } - - public static NotificationMessage formatMessage(long userId, Event event, Position position, String templatePath) { - VelocityContext velocityContext = prepareContext(userId, event, position); return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index f91ec25a0..bcce9a4d8 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -20,12 +20,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationMessage; import org.traccar.notification.NotificationFormatter; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -69,7 +71,8 @@ public class NotificatorFirebase extends Notificator { final User user = Context.getPermissionsManager().getUser(userId); if (user.getAttributes().containsKey("notificationTokens")) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 9b5637ed8..eb7f399eb 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -17,11 +17,13 @@ package org.traccar.notificators; import org.traccar.Context; +import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.notification.NotificationMessage; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; +import org.traccar.session.cache.CacheManager; import javax.mail.MessagingException; @@ -30,7 +32,8 @@ public final class NotificatorMail extends Notificator { @Override public void sendSync(long userId, Event event, Position position) throws MessageException { try { - NotificationMessage fullMessage = NotificationFormatter.formatMessage(userId, event, position, "full"); + NotificationMessage fullMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "full"); Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 456c2fe4f..73fad9bd2 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -19,12 +19,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -77,7 +79,8 @@ public class NotificatorPushover extends Notificator { return; } - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Message message = new Message(); message.token = token; diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index fb817b112..09eb65b0c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -25,6 +25,7 @@ import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; public final class NotificatorSms extends Notificator { @@ -32,7 +33,8 @@ public final class NotificatorSms extends Notificator { public void sendAsync(long userId, Event event, Position position) { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), shortMessage.getBody(), false); @@ -43,7 +45,8 @@ public final class NotificatorSms extends Notificator { public void sendSync(long userId, Event event, Position position) throws MessageException, InterruptedException { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), shortMessage.getBody(), false); diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 70148110c..a8e69e77d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -20,12 +20,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.model.User; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -99,7 +101,8 @@ public class NotificatorTelegram extends Notificator { @Override public void sendSync(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java index e4b905702..818142b16 100644 --- a/src/main/java/org/traccar/reports/Events.java +++ b/src/main/java/org/traccar/reports/Events.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"); @@ -34,6 +34,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.model.DeviceReport; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; public final class Events { @@ -41,7 +42,9 @@ public final class Events { private Events() { } - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + public static Collection getObjects( + Storage storage, long userId, + Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); @@ -53,9 +56,9 @@ public final class Events { if (all || types.contains(event.getType())) { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); - if ((geofenceId == 0 || Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) + if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) && (maintenanceId == 0 - || Context.getMaintenancesManager().checkItemPermission(userId, maintenanceId))) { + || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { result.add(event); } } @@ -64,8 +67,9 @@ public final class Events { return result; } - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, + public static void getExcel( + OutputStream outputStream, Storage storage, long userId, + Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesEvents = new ArrayList<>(); @@ -82,20 +86,18 @@ public final class Events { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); if (geofenceId != 0) { - if (Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) { - Geofence geofence = Context.getGeofenceManager().getById(geofenceId); - if (geofence != null) { - geofenceNames.put(geofenceId, geofence.getName()); - } + Geofence geofence = ReportUtils.getObject( + storage, userId, Geofence.class, geofenceId); + if (geofence != null) { + geofenceNames.put(geofenceId, geofence.getName()); } else { iterator.remove(); } } else if (maintenanceId != 0) { - if (Context.getMaintenancesManager().checkItemPermission(userId, maintenanceId)) { - Maintenance maintenance = Context.getMaintenancesManager().getById(maintenanceId); - if (maintenance != null) { - maintenanceNames.put(maintenanceId, maintenance.getName()); - } + Maintenance maintenance = ReportUtils.getObject( + storage, userId, Maintenance.class, maintenanceId); + if (maintenance != null) { + maintenanceNames.put(maintenanceId, maintenance.getName()); } else { iterator.remove(); } diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index 413d49ad7..98a80a23e 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -31,6 +31,8 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; +import org.traccar.model.BaseModel; +import org.traccar.model.User; import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; @@ -39,6 +41,11 @@ import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import java.io.IOException; import java.io.InputStream; @@ -59,6 +66,15 @@ public final class ReportUtils { private ReportUtils() { } + public static T getObject( + Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { + return storage.getObject(clazz, new Request( + new Columns.Include("id"), + new Condition.And( + new Condition.Equals("id", "id", objectId), + new Condition.Permission(User.class, userId, clazz)))); + } + public static void checkPeriodLimit(Date from, Date to) { long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { -- cgit v1.2.3 From b45b64ce97113c68ef6118665c4a8b0106249264 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 10:52:23 -0700 Subject: Move common report classes --- src/main/java/org/traccar/Context.java | 2 +- src/main/java/org/traccar/MainModule.java | 2 +- .../java/org/traccar/handler/MotionHandler.java | 2 +- .../traccar/handler/events/MotionEventHandler.java | 4 +- .../notification/NotificationFormatter.java | 2 +- .../notification/TextTemplateFormatter.java | 2 +- src/main/java/org/traccar/reports/Events.java | 1 + src/main/java/org/traccar/reports/ReportUtils.java | 388 --------------------- src/main/java/org/traccar/reports/Route.java | 1 + src/main/java/org/traccar/reports/Stops.java | 1 + src/main/java/org/traccar/reports/Summary.java | 1 + src/main/java/org/traccar/reports/Trips.java | 1 + .../org/traccar/reports/common/ReportUtils.java | 387 ++++++++++++++++++++ .../org/traccar/reports/common/TripsConfig.java | 74 ++++ .../org/traccar/reports/model/TripsConfig.java | 74 ---- .../org/traccar/handler/MotionHandlerTest.java | 2 +- .../handler/events/MotionEventHandlerTest.java | 2 +- .../java/org/traccar/reports/ReportUtilsTest.java | 3 +- 18 files changed, 477 insertions(+), 472 deletions(-) delete mode 100644 src/main/java/org/traccar/reports/ReportUtils.java create mode 100644 src/main/java/org/traccar/reports/common/ReportUtils.java create mode 100644 src/main/java/org/traccar/reports/common/TripsConfig.java delete mode 100644 src/main/java/org/traccar/reports/model/TripsConfig.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index a833d0c52..dde98f505 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -48,7 +48,7 @@ import org.traccar.model.Notification; import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import org.traccar.session.ConnectionManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 219a8fc11..fb70a51c6 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -58,7 +58,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 864eb455d..7b2c04ecf 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -19,7 +19,7 @@ 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 org.traccar.reports.common.TripsConfig; import javax.inject.Inject; diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index e27faf9ce..57d2bc1c5 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -26,8 +26,8 @@ import org.traccar.model.Device; import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.ReportUtils; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import javax.inject.Inject; diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 107426e06..30a862372 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -24,7 +24,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.reports.ReportUtils; +import org.traccar.reports.common.ReportUtils; import org.traccar.session.cache.CacheManager; public final class NotificationFormatter { diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index b7058c824..469de2d4a 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -24,7 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.User; -import org.traccar.reports.ReportUtils; +import org.traccar.reports.common.ReportUtils; import java.io.StringWriter; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java index 818142b16..c5db305ed 100644 --- a/src/main/java/org/traccar/reports/Events.java +++ b/src/main/java/org/traccar/reports/Events.java @@ -33,6 +33,7 @@ import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java deleted file mode 100644 index 98a80a23e..000000000 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * 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"); - * 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.reports; - -import org.apache.velocity.tools.generic.DateTool; -import org.apache.velocity.tools.generic.NumberTool; -import org.jxls.area.Area; -import org.jxls.builder.xls.XlsCommentAreaBuilder; -import org.jxls.common.CellRef; -import org.jxls.formula.StandardFormulaProcessor; -import org.jxls.transform.Transformer; -import org.jxls.transform.poi.PoiTransformer; -import org.jxls.util.TransformerFactory; -import org.traccar.Context; -import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.BaseModel; -import org.traccar.model.User; -import org.traccar.session.DeviceState; -import org.traccar.model.Driver; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; -import org.traccar.reports.model.TripsConfig; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -public final class ReportUtils { - - private ReportUtils() { - } - - public static T getObject( - Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { - return storage.getObject(clazz, new Request( - new Columns.Include("id"), - new Condition.And( - new Condition.Equals("id", "id", objectId), - new Condition.Permission(User.class, userId, clazz)))); - } - - public static void checkPeriodLimit(Date from, Date to) { - long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; - if (limit > 0 && to.getTime() - from.getTime() > limit) { - throw new IllegalArgumentException("Time period exceeds the limit"); - } - } - - public static String getDistanceUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); - } - - public static String getSpeedUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); - } - - public static String getVolumeUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(long userId) { - String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - - public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { - Collection result = new LinkedHashSet<>(deviceIds); - for (long groupId : groupIds) { - result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); - } - return result; - } - - public static double calculateDistance(Position firstPosition, Position lastPosition) { - return calculateDistance(firstPosition, lastPosition, true); - } - - public static double calculateDistance(Position firstPosition, Position lastPosition, boolean useOdometer) { - double distance = 0.0; - double firstOdometer = firstPosition.getDouble(Position.KEY_ODOMETER); - double lastOdometer = lastPosition.getDouble(Position.KEY_ODOMETER); - - if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { - distance = lastOdometer - firstOdometer; - } else if (firstPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE) - && lastPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE)) { - distance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE) - - firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE); - } - return distance; - } - - public static double calculateFuel(Position firstPosition, Position lastPosition) { - - if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null - && lastPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null) { - - BigDecimal value = BigDecimal.valueOf(firstPosition.getDouble(Position.KEY_FUEL_LEVEL) - - lastPosition.getDouble(Position.KEY_FUEL_LEVEL)); - return value.setScale(1, RoundingMode.HALF_EVEN).doubleValue(); - } - return 0; - } - - public static String findDriver(Position firstPosition, Position lastPosition) { - if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } - return null; - } - - public static String findDriverName(String driverUniqueId) { - if (driverUniqueId != null && Context.getDriversManager() != null) { - Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId); - if (driver != null) { - return driver.getName(); - } - } - return null; - } - - public static org.jxls.common.Context initializeContext(long userId) { - org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); - jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); - jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); - jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); - jxlsContext.putVar("dateTool", new DateTool()); - jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", getTimezone(userId)); - jxlsContext.putVar("locale", Locale.getDefault()); - jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); - return jxlsContext; - } - - public static void processTemplateWithSheets( - InputStream templateStream, OutputStream targetStream, - org.jxls.common.Context jxlsContext) throws IOException { - - Transformer transformer = TransformerFactory.createTransformer(templateStream, targetStream); - List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); - for (Area xlsArea : xlsAreas) { - xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext); - xlsArea.setFormulaProcessor(new StandardFormulaProcessor()); - xlsArea.processFormulas(); - } - transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName()); - transformer.write(); - } - - private static TripReport calculateTrip( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { - - Position startTrip = positions.get(startIndex); - Position endTrip = positions.get(endIndex); - - double speedMax = 0; - for (int i = startIndex; i <= endIndex; i++) { - double speed = positions.get(i).getSpeed(); - if (speed > speedMax) { - speedMax = speed; - } - } - - TripReport trip = new TripReport(); - - long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); - long deviceId = startTrip.getDeviceId(); - trip.setDeviceId(deviceId); - trip.setDeviceName(identityManager.getById(deviceId).getName()); - - trip.setStartPositionId(startTrip.getId()); - trip.setStartLat(startTrip.getLatitude()); - trip.setStartLon(startTrip.getLongitude()); - trip.setStartTime(startTrip.getFixTime()); - String startAddress = startTrip.getAddress(); - if (startAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - startAddress = Context.getGeocoder().getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); - } - trip.setStartAddress(startAddress); - - trip.setEndPositionId(endTrip.getId()); - trip.setEndLat(endTrip.getLatitude()); - trip.setEndLon(endTrip.getLongitude()); - trip.setEndTime(endTrip.getFixTime()); - String endAddress = endTrip.getAddress(); - if (endAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - endAddress = Context.getGeocoder().getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); - } - trip.setEndAddress(endAddress); - - trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer)); - trip.setDuration(tripDuration); - if (tripDuration > 0) { - trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); - } - trip.setMaxSpeed(speedMax); - trip.setSpentFuel(calculateFuel(startTrip, endTrip)); - - trip.setDriverUniqueId(findDriver(startTrip, endTrip)); - trip.setDriverName(findDriverName(trip.getDriverUniqueId())); - - if (!ignoreOdometer - && startTrip.getDouble(Position.KEY_ODOMETER) != 0 - && endTrip.getDouble(Position.KEY_ODOMETER) != 0) { - trip.setStartOdometer(startTrip.getDouble(Position.KEY_ODOMETER)); - trip.setEndOdometer(endTrip.getDouble(Position.KEY_ODOMETER)); - } else { - trip.setStartOdometer(startTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); - trip.setEndOdometer(endTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - return trip; - } - - private static StopReport calculateStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { - - Position startStop = positions.get(startIndex); - Position endStop = positions.get(endIndex); - - StopReport stop = new StopReport(); - - long deviceId = startStop.getDeviceId(); - stop.setDeviceId(deviceId); - stop.setDeviceName(identityManager.getById(deviceId).getName()); - - stop.setPositionId(startStop.getId()); - stop.setLatitude(startStop.getLatitude()); - stop.setLongitude(startStop.getLongitude()); - stop.setStartTime(startStop.getFixTime()); - String address = startStop.getAddress(); - if (address == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - address = Context.getGeocoder().getAddress(stop.getLatitude(), stop.getLongitude(), null); - } - stop.setAddress(address); - - stop.setEndTime(endStop.getFixTime()); - - long stopDuration = endStop.getFixTime().getTime() - startStop.getFixTime().getTime(); - stop.setDuration(stopDuration); - stop.setSpentFuel(calculateFuel(startStop, endStop)); - - if (startStop.getAttributes().containsKey(Position.KEY_HOURS) - && endStop.getAttributes().containsKey(Position.KEY_HOURS)) { - stop.setEngineHours(endStop.getLong(Position.KEY_HOURS) - startStop.getLong(Position.KEY_HOURS)); - } - - if (!ignoreOdometer - && startStop.getDouble(Position.KEY_ODOMETER) != 0 - && endStop.getDouble(Position.KEY_ODOMETER) != 0) { - stop.setStartOdometer(startStop.getDouble(Position.KEY_ODOMETER)); - stop.setEndOdometer(endStop.getDouble(Position.KEY_ODOMETER)); - } else { - stop.setStartOdometer(startStop.getDouble(Position.KEY_TOTAL_DISTANCE)); - stop.setEndOdometer(endStop.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - return stop; - - } - - private static T calculateTripOrStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { - - if (reportClass.equals(TripReport.class)) { - return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); - } else { - return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); - } - } - - private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { - if (tripsConfig.getMinimalNoDataDuration() > 0) { - boolean beforeGap = index < positions.size() - 1 - && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - boolean afterGap = index > 0 - && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - if (beforeGap || afterGap) { - return false; - } - } - if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) - && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { - return positions.get(index).getBoolean(Position.KEY_MOTION); - } else { - return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); - } - } - - public static Collection detectTripsAndStops( - IdentityManager identityManager, DeviceManager deviceManager, - Collection positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { - - Collection result = new ArrayList<>(); - - ArrayList positions = new ArrayList<>(positionCollection); - if (!positions.isEmpty()) { - boolean trips = reportClass.equals(TripReport.class); - MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); - int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; - int startNoEventIndex = -1; - for (int i = 0; i < positions.size(); i++) { - Map event = motionHandler.updateMotionState(deviceState, positions.get(i), - isMoving(positions, i, tripsConfig)); - if (startEventIndex == -1 - && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips == deviceState.getMotionState() && event != null)) { - startEventIndex = i; - startNoEventIndex = -1; - } else if (trips != deviceState.getMotionState() && startEventIndex != -1 - && deviceState.getMotionPosition() == null && event == null) { - startEventIndex = -1; - } - if (startNoEventIndex == -1 - && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips != deviceState.getMotionState() && event != null)) { - startNoEventIndex = i; - } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { - startNoEventIndex = -1; - } - if (startEventIndex != -1 && startNoEventIndex != -1 && event != null - && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(identityManager, positions, - startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); - startEventIndex = -1; - } - } - if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(identityManager, positions, - startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, - ignoreOdometer, reportClass)); - } - } - - return result; - } - -} diff --git a/src/main/java/org/traccar/reports/Route.java b/src/main/java/org/traccar/reports/Route.java index 4a5edd295..d7745157a 100644 --- a/src/main/java/org/traccar/reports/Route.java +++ b/src/main/java/org/traccar/reports/Route.java @@ -29,6 +29,7 @@ import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java index 36a4a7549..82eb62f66 100644 --- a/src/main/java/org/traccar/reports/Stops.java +++ b/src/main/java/org/traccar/reports/Stops.java @@ -32,6 +32,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.StopReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index f00b1ca57..20d80a9f5 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -29,6 +29,7 @@ import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java index 1461b869e..58131debb 100644 --- a/src/main/java/org/traccar/reports/Trips.java +++ b/src/main/java/org/traccar/reports/Trips.java @@ -31,6 +31,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.TripReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java new file mode 100644 index 000000000..27972b453 --- /dev/null +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -0,0 +1,387 @@ +/* + * 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"); + * 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.reports.common; + +import org.apache.velocity.tools.generic.DateTool; +import org.apache.velocity.tools.generic.NumberTool; +import org.jxls.area.Area; +import org.jxls.builder.xls.XlsCommentAreaBuilder; +import org.jxls.common.CellRef; +import org.jxls.formula.StandardFormulaProcessor; +import org.jxls.transform.Transformer; +import org.jxls.transform.poi.PoiTransformer; +import org.jxls.util.TransformerFactory; +import org.traccar.Context; +import org.traccar.config.Keys; +import org.traccar.database.DeviceManager; +import org.traccar.database.IdentityManager; +import org.traccar.handler.events.MotionEventHandler; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.BaseModel; +import org.traccar.model.User; +import org.traccar.session.DeviceState; +import org.traccar.model.Driver; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.reports.model.BaseReport; +import org.traccar.reports.model.StopReport; +import org.traccar.reports.model.TripReport; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +public final class ReportUtils { + + private ReportUtils() { + } + + public static T getObject( + Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { + return storage.getObject(clazz, new Request( + new Columns.Include("id"), + new Condition.And( + new Condition.Equals("id", "id", objectId), + new Condition.Permission(User.class, userId, clazz)))); + } + + public static void checkPeriodLimit(Date from, Date to) { + long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; + if (limit > 0 && to.getTime() - from.getTime() > limit) { + throw new IllegalArgumentException("Time period exceeds the limit"); + } + } + + public static String getDistanceUnit(long userId) { + return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); + } + + public static String getSpeedUnit(long userId) { + return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); + } + + public static String getVolumeUnit(long userId) { + return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(long userId) { + String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { + Collection result = new LinkedHashSet<>(deviceIds); + for (long groupId : groupIds) { + result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); + } + return result; + } + + public static double calculateDistance(Position firstPosition, Position lastPosition) { + return calculateDistance(firstPosition, lastPosition, true); + } + + public static double calculateDistance(Position firstPosition, Position lastPosition, boolean useOdometer) { + double distance = 0.0; + double firstOdometer = firstPosition.getDouble(Position.KEY_ODOMETER); + double lastOdometer = lastPosition.getDouble(Position.KEY_ODOMETER); + + if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { + distance = lastOdometer - firstOdometer; + } else if (firstPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE) + && lastPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE)) { + distance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE) + - firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE); + } + return distance; + } + + public static double calculateFuel(Position firstPosition, Position lastPosition) { + + if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null + && lastPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null) { + + BigDecimal value = BigDecimal.valueOf(firstPosition.getDouble(Position.KEY_FUEL_LEVEL) + - lastPosition.getDouble(Position.KEY_FUEL_LEVEL)); + return value.setScale(1, RoundingMode.HALF_EVEN).doubleValue(); + } + return 0; + } + + public static String findDriver(Position firstPosition, Position lastPosition) { + if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); + } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); + } + return null; + } + + public static String findDriverName(String driverUniqueId) { + if (driverUniqueId != null && Context.getDriversManager() != null) { + Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId); + if (driver != null) { + return driver.getName(); + } + } + return null; + } + + public static org.jxls.common.Context initializeContext(long userId) { + org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); + jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); + jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); + jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); + jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); + jxlsContext.putVar("dateTool", new DateTool()); + jxlsContext.putVar("numberTool", new NumberTool()); + jxlsContext.putVar("timezone", getTimezone(userId)); + jxlsContext.putVar("locale", Locale.getDefault()); + jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); + return jxlsContext; + } + + public static void processTemplateWithSheets( + InputStream templateStream, OutputStream targetStream, + org.jxls.common.Context jxlsContext) throws IOException { + + Transformer transformer = TransformerFactory.createTransformer(templateStream, targetStream); + List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); + for (Area xlsArea : xlsAreas) { + xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext); + xlsArea.setFormulaProcessor(new StandardFormulaProcessor()); + xlsArea.processFormulas(); + } + transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName()); + transformer.write(); + } + + private static TripReport calculateTrip( + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { + + Position startTrip = positions.get(startIndex); + Position endTrip = positions.get(endIndex); + + double speedMax = 0; + for (int i = startIndex; i <= endIndex; i++) { + double speed = positions.get(i).getSpeed(); + if (speed > speedMax) { + speedMax = speed; + } + } + + TripReport trip = new TripReport(); + + long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); + long deviceId = startTrip.getDeviceId(); + trip.setDeviceId(deviceId); + trip.setDeviceName(identityManager.getById(deviceId).getName()); + + trip.setStartPositionId(startTrip.getId()); + trip.setStartLat(startTrip.getLatitude()); + trip.setStartLon(startTrip.getLongitude()); + trip.setStartTime(startTrip.getFixTime()); + String startAddress = startTrip.getAddress(); + if (startAddress == null && Context.getGeocoder() != null + && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { + startAddress = Context.getGeocoder().getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); + } + trip.setStartAddress(startAddress); + + trip.setEndPositionId(endTrip.getId()); + trip.setEndLat(endTrip.getLatitude()); + trip.setEndLon(endTrip.getLongitude()); + trip.setEndTime(endTrip.getFixTime()); + String endAddress = endTrip.getAddress(); + if (endAddress == null && Context.getGeocoder() != null + && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { + endAddress = Context.getGeocoder().getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); + } + trip.setEndAddress(endAddress); + + trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer)); + trip.setDuration(tripDuration); + if (tripDuration > 0) { + trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); + } + trip.setMaxSpeed(speedMax); + trip.setSpentFuel(calculateFuel(startTrip, endTrip)); + + trip.setDriverUniqueId(findDriver(startTrip, endTrip)); + trip.setDriverName(findDriverName(trip.getDriverUniqueId())); + + if (!ignoreOdometer + && startTrip.getDouble(Position.KEY_ODOMETER) != 0 + && endTrip.getDouble(Position.KEY_ODOMETER) != 0) { + trip.setStartOdometer(startTrip.getDouble(Position.KEY_ODOMETER)); + trip.setEndOdometer(endTrip.getDouble(Position.KEY_ODOMETER)); + } else { + trip.setStartOdometer(startTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); + trip.setEndOdometer(endTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + + return trip; + } + + private static StopReport calculateStop( + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { + + Position startStop = positions.get(startIndex); + Position endStop = positions.get(endIndex); + + StopReport stop = new StopReport(); + + long deviceId = startStop.getDeviceId(); + stop.setDeviceId(deviceId); + stop.setDeviceName(identityManager.getById(deviceId).getName()); + + stop.setPositionId(startStop.getId()); + stop.setLatitude(startStop.getLatitude()); + stop.setLongitude(startStop.getLongitude()); + stop.setStartTime(startStop.getFixTime()); + String address = startStop.getAddress(); + if (address == null && Context.getGeocoder() != null + && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { + address = Context.getGeocoder().getAddress(stop.getLatitude(), stop.getLongitude(), null); + } + stop.setAddress(address); + + stop.setEndTime(endStop.getFixTime()); + + long stopDuration = endStop.getFixTime().getTime() - startStop.getFixTime().getTime(); + stop.setDuration(stopDuration); + stop.setSpentFuel(calculateFuel(startStop, endStop)); + + if (startStop.getAttributes().containsKey(Position.KEY_HOURS) + && endStop.getAttributes().containsKey(Position.KEY_HOURS)) { + stop.setEngineHours(endStop.getLong(Position.KEY_HOURS) - startStop.getLong(Position.KEY_HOURS)); + } + + if (!ignoreOdometer + && startStop.getDouble(Position.KEY_ODOMETER) != 0 + && endStop.getDouble(Position.KEY_ODOMETER) != 0) { + stop.setStartOdometer(startStop.getDouble(Position.KEY_ODOMETER)); + stop.setEndOdometer(endStop.getDouble(Position.KEY_ODOMETER)); + } else { + stop.setStartOdometer(startStop.getDouble(Position.KEY_TOTAL_DISTANCE)); + stop.setEndOdometer(endStop.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + + return stop; + + } + + private static T calculateTripOrStop( + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { + + if (reportClass.equals(TripReport.class)) { + return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); + } else { + return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); + } + } + + private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { + if (tripsConfig.getMinimalNoDataDuration() > 0) { + boolean beforeGap = index < positions.size() - 1 + && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + boolean afterGap = index > 0 + && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + if (beforeGap || afterGap) { + return false; + } + } + if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) + && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { + return positions.get(index).getBoolean(Position.KEY_MOTION); + } else { + return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); + } + } + + public static Collection detectTripsAndStops( + IdentityManager identityManager, DeviceManager deviceManager, + Collection positionCollection, + TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { + + Collection result = new ArrayList<>(); + + ArrayList positions = new ArrayList<>(positionCollection); + if (!positions.isEmpty()) { + boolean trips = reportClass.equals(TripReport.class); + MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); + int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; + int startNoEventIndex = -1; + for (int i = 0; i < positions.size(); i++) { + Map event = motionHandler.updateMotionState(deviceState, positions.get(i), + isMoving(positions, i, tripsConfig)); + if (startEventIndex == -1 + && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null + || trips == deviceState.getMotionState() && event != null)) { + startEventIndex = i; + startNoEventIndex = -1; + } else if (trips != deviceState.getMotionState() && startEventIndex != -1 + && deviceState.getMotionPosition() == null && event == null) { + startEventIndex = -1; + } + if (startNoEventIndex == -1 + && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null + || trips != deviceState.getMotionState() && event != null)) { + startNoEventIndex = i; + } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { + startNoEventIndex = -1; + } + if (startEventIndex != -1 && startNoEventIndex != -1 && event != null + && trips != deviceState.getMotionState()) { + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + startEventIndex = -1; + } + } + if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, + ignoreOdometer, reportClass)); + } + } + + return result; + } + +} diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java new file mode 100644 index 000000000..9a7cebafb --- /dev/null +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -0,0 +1,74 @@ +/* + * 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"); + * 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.reports.common; + +public class TripsConfig { + + public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, + long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { + this.minimalTripDistance = minimalTripDistance; + this.minimalTripDuration = minimalTripDuration; + this.minimalParkingDuration = minimalParkingDuration; + this.minimalNoDataDuration = minimalNoDataDuration; + this.useIgnition = useIgnition; + this.processInvalidPositions = processInvalidPositions; + this.speedThreshold = speedThreshold; + } + + private final double minimalTripDistance; + + public double getMinimalTripDistance() { + return minimalTripDistance; + } + + private final long minimalTripDuration; + + public long getMinimalTripDuration() { + return minimalTripDuration; + } + + private final long minimalParkingDuration; + + public long getMinimalParkingDuration() { + return minimalParkingDuration; + } + + private final long minimalNoDataDuration; + + public long getMinimalNoDataDuration() { + return minimalNoDataDuration; + } + + private final boolean useIgnition; + + public boolean getUseIgnition() { + return useIgnition; + } + + private final boolean processInvalidPositions; + + public boolean getProcessInvalidPositions() { + return processInvalidPositions; + } + + private final double speedThreshold; + + public double getSpeedThreshold() { + return speedThreshold; + } + +} diff --git a/src/main/java/org/traccar/reports/model/TripsConfig.java b/src/main/java/org/traccar/reports/model/TripsConfig.java deleted file mode 100644 index 34c445f8b..000000000 --- a/src/main/java/org/traccar/reports/model/TripsConfig.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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"); - * 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.reports.model; - -public class TripsConfig { - - public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, - long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { - this.minimalTripDistance = minimalTripDistance; - this.minimalTripDuration = minimalTripDuration; - this.minimalParkingDuration = minimalParkingDuration; - this.minimalNoDataDuration = minimalNoDataDuration; - this.useIgnition = useIgnition; - this.processInvalidPositions = processInvalidPositions; - this.speedThreshold = speedThreshold; - } - - private final double minimalTripDistance; - - public double getMinimalTripDistance() { - return minimalTripDistance; - } - - private final long minimalTripDuration; - - public long getMinimalTripDuration() { - return minimalTripDuration; - } - - private final long minimalParkingDuration; - - public long getMinimalParkingDuration() { - return minimalParkingDuration; - } - - private final long minimalNoDataDuration; - - public long getMinimalNoDataDuration() { - return minimalNoDataDuration; - } - - private final boolean useIgnition; - - public boolean getUseIgnition() { - return useIgnition; - } - - private final boolean processInvalidPositions; - - public boolean getProcessInvalidPositions() { - return processInvalidPositions; - } - - private final double speedThreshold; - - public double getSpeedThreshold() { - return speedThreshold; - } - -} diff --git a/src/test/java/org/traccar/handler/MotionHandlerTest.java b/src/test/java/org/traccar/handler/MotionHandlerTest.java index aa73ac60a..93fd16206 100644 --- a/src/test/java/org/traccar/handler/MotionHandlerTest.java +++ b/src/test/java/org/traccar/handler/MotionHandlerTest.java @@ -2,7 +2,7 @@ package org.traccar.handler; import org.junit.Test; import org.traccar.model.Position; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 94dab4049..780d1b833 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -4,7 +4,7 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import org.traccar.session.DeviceState; import java.text.DateFormat; diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index be473a341..247e43499 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -5,9 +5,10 @@ import org.traccar.BaseTest; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import java.text.DateFormat; import java.text.ParseException; -- cgit v1.2.3 From 94a2a94330d82fa1c1960b8783e5061c188196e3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 10:55:50 -0700 Subject: Rename report models --- .../org/traccar/api/resource/ReportResource.java | 12 +- src/main/java/org/traccar/reports/Events.java | 6 +- src/main/java/org/traccar/reports/Route.java | 6 +- src/main/java/org/traccar/reports/Stops.java | 18 +-- src/main/java/org/traccar/reports/Summary.java | 22 ++-- src/main/java/org/traccar/reports/Trips.java | 20 ++-- .../org/traccar/reports/common/ReportUtils.java | 22 ++-- .../java/org/traccar/reports/model/BaseReport.java | 126 -------------------- .../org/traccar/reports/model/BaseReportItem.java | 126 ++++++++++++++++++++ .../org/traccar/reports/model/DeviceReport.java | 55 --------- .../traccar/reports/model/DeviceReportSection.java | 55 +++++++++ .../java/org/traccar/reports/model/StopReport.java | 80 ------------- .../org/traccar/reports/model/StopReportItem.java | 80 +++++++++++++ .../org/traccar/reports/model/SummaryReport.java | 30 ----- .../traccar/reports/model/SummaryReportItem.java | 30 +++++ .../java/org/traccar/reports/model/TripReport.java | 130 --------------------- .../org/traccar/reports/model/TripReportItem.java | 130 +++++++++++++++++++++ .../java/org/traccar/reports/ReportUtilsTest.java | 82 ++++++------- 18 files changed, 515 insertions(+), 515 deletions(-) delete mode 100644 src/main/java/org/traccar/reports/model/BaseReport.java create mode 100644 src/main/java/org/traccar/reports/model/BaseReportItem.java delete mode 100644 src/main/java/org/traccar/reports/model/DeviceReport.java create mode 100644 src/main/java/org/traccar/reports/model/DeviceReportSection.java delete mode 100644 src/main/java/org/traccar/reports/model/StopReport.java create mode 100644 src/main/java/org/traccar/reports/model/StopReportItem.java delete mode 100644 src/main/java/org/traccar/reports/model/SummaryReport.java create mode 100644 src/main/java/org/traccar/reports/model/SummaryReportItem.java delete mode 100644 src/main/java/org/traccar/reports/model/TripReport.java create mode 100644 src/main/java/org/traccar/reports/model/TripReportItem.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index a7bbe1067..5346df31b 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -46,9 +46,9 @@ import org.traccar.model.UserRestrictions; import org.traccar.reports.Events; import org.traccar.reports.Summary; import org.traccar.reports.Trips; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.SummaryReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.StopReportItem; +import org.traccar.reports.model.SummaryReportItem; +import org.traccar.reports.model.TripReportItem; import org.traccar.reports.Route; import org.traccar.reports.Stops; import org.traccar.storage.StorageException; @@ -147,7 +147,7 @@ public class ReportResource extends BaseResource { @Path("summary") @GET - public Collection getSummary( + public Collection getSummary( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) throws StorageException { @@ -174,7 +174,7 @@ public class ReportResource extends BaseResource { @Path("trips") @GET @Produces(MediaType.APPLICATION_JSON) - public Collection getTrips( + public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); @@ -199,7 +199,7 @@ public class ReportResource extends BaseResource { @Path("stops") @GET @Produces(MediaType.APPLICATION_JSON) - public Collection getStops( + public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java index c5db305ed..130fba724 100644 --- a/src/main/java/org/traccar/reports/Events.java +++ b/src/main/java/org/traccar/reports/Events.java @@ -34,7 +34,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; +import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -73,7 +73,7 @@ public final class Events { Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesEvents = new ArrayList<>(); + ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); @@ -107,7 +107,7 @@ public final class Events { iterator.remove(); } } - DeviceReport deviceEvents = new DeviceReport(); + DeviceReportSection deviceEvents = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/Route.java b/src/main/java/org/traccar/reports/Route.java index d7745157a..5b8629aad 100644 --- a/src/main/java/org/traccar/reports/Route.java +++ b/src/main/java/org/traccar/reports/Route.java @@ -30,7 +30,7 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; +import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; public final class Route { @@ -53,13 +53,13 @@ public final class Route { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesRoutes = new ArrayList<>(); + ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection positions = Context.getDataManager() .getPositions(deviceId, from, to); - DeviceReport deviceRoutes = new DeviceReport(); + DeviceReportSection deviceRoutes = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java index 82eb62f66..e688d53da 100644 --- a/src/main/java/org/traccar/reports/Stops.java +++ b/src/main/java/org/traccar/reports/Stops.java @@ -33,8 +33,8 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; -import org.traccar.reports.model.StopReport; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.StopReportItem; import org.traccar.storage.StorageException; public final class Stops { @@ -42,7 +42,7 @@ public final class Stops { private Stops() { } - private static Collection detectStops(long deviceId, Date from, Date to) throws StorageException { + private static Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -51,14 +51,14 @@ public final class Stops { return ReportUtils.detectTripsAndStops( identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, StopReport.class); + Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); } - public static Collection getObjects( + public static Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); + ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectStops(deviceId, from, to)); @@ -70,12 +70,12 @@ public final class Stops { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesStops = new ArrayList<>(); + ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection stops = detectStops(deviceId, from, to); - DeviceReport deviceStops = new DeviceReport(); + Collection stops = detectStops(deviceId, from, to); + DeviceReportSection deviceStops = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index 20d80a9f5..30c4cb057 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -30,7 +30,7 @@ import org.traccar.Context; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.SummaryReport; +import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.StorageException; public final class Summary { @@ -38,8 +38,8 @@ public final class Summary { private Summary() { } - private static SummaryReport calculateSummaryResult(long deviceId, Collection positions) { - SummaryReport result = new SummaryReport(); + private static SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { + SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(deviceId); result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); if (positions != null && !positions.isEmpty()) { @@ -97,12 +97,12 @@ public final class Summary { return calendar.get(Calendar.DAY_OF_MONTH); } - private static Collection calculateSummaryResults( + private static Collection calculateSummaryResults( long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); - ArrayList results = new ArrayList<>(); + ArrayList results = new ArrayList<>(); if (daily && !positions.isEmpty()) { int startIndex = 0; int startDay = getDay(userId, positions.iterator().next().getFixTime()); @@ -122,14 +122,14 @@ public final class Summary { return results; } - public static Collection getObjects(long userId, Collection deviceIds, - Collection groupIds, Date from, Date to, boolean daily) throws StorageException { + public static Collection getObjects(long userId, Collection deviceIds, + Collection groupIds, Date from, Date to, boolean daily) throws StorageException { ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); + ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); - for (SummaryReport summaryReport : deviceResults) { + Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { result.add(summaryReport); } @@ -142,7 +142,7 @@ public final class Summary { long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); + Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java index 58131debb..74e24cf2f 100644 --- a/src/main/java/org/traccar/reports/Trips.java +++ b/src/main/java/org/traccar/reports/Trips.java @@ -32,8 +32,8 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.TripReportItem; import org.traccar.storage.StorageException; public final class Trips { @@ -41,7 +41,7 @@ public final class Trips { private Trips() { } - private static Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { + private static Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -50,13 +50,13 @@ public final class Trips { return ReportUtils.detectTripsAndStops( identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, TripReport.class); + Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); } - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { + public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); + ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectTrips(deviceId, from, to)); @@ -68,12 +68,12 @@ public final class Trips { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesTrips = new ArrayList<>(); + ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection trips = detectTrips(deviceId, from, to); - DeviceReport deviceTrips = new DeviceReport(); + Collection trips = detectTrips(deviceId, from, to); + DeviceReportSection deviceTrips = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 27972b453..b56b58a58 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -37,9 +37,9 @@ import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.BaseReportItem; +import org.traccar.reports.model.StopReportItem; +import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -185,7 +185,7 @@ public final class ReportUtils { transformer.write(); } - private static TripReport calculateTrip( + private static TripReportItem calculateTrip( IdentityManager identityManager, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { @@ -200,7 +200,7 @@ public final class ReportUtils { } } - TripReport trip = new TripReport(); + TripReportItem trip = new TripReportItem(); long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); @@ -253,14 +253,14 @@ public final class ReportUtils { return trip; } - private static StopReport calculateStop( + private static StopReportItem calculateStop( IdentityManager identityManager, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); - StopReport stop = new StopReport(); + StopReportItem stop = new StopReportItem(); long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); @@ -302,11 +302,11 @@ public final class ReportUtils { } - private static T calculateTripOrStop( + private static T calculateTripOrStop( IdentityManager identityManager, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { - if (reportClass.equals(TripReport.class)) { + if (reportClass.equals(TripReportItem.class)) { return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); } else { return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); @@ -333,7 +333,7 @@ public final class ReportUtils { } } - public static Collection detectTripsAndStops( + public static Collection detectTripsAndStops( IdentityManager identityManager, DeviceManager deviceManager, Collection positionCollection, TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { @@ -342,7 +342,7 @@ public final class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { - boolean trips = reportClass.equals(TripReport.class); + boolean trips = reportClass.equals(TripReportItem.class); MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); diff --git a/src/main/java/org/traccar/reports/model/BaseReport.java b/src/main/java/org/traccar/reports/model/BaseReport.java deleted file mode 100644 index 928c0557d..000000000 --- a/src/main/java/org/traccar/reports/model/BaseReport.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports.model; - -import java.util.Date; - -public class BaseReport { - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - - private String deviceName; - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - private double distance; - - public double getDistance() { - return distance; - } - - public void setDistance(double distance) { - this.distance = distance; - } - - public void addDistance(double distance) { - this.distance += distance; - } - - private double averageSpeed; - - public double getAverageSpeed() { - return averageSpeed; - } - - public void setAverageSpeed(double averageSpeed) { - this.averageSpeed = averageSpeed; - } - - private double maxSpeed; - - public double getMaxSpeed() { - return maxSpeed; - } - - public void setMaxSpeed(double maxSpeed) { - this.maxSpeed = maxSpeed; - } - - private double spentFuel; - - public double getSpentFuel() { - return spentFuel; - } - - public void setSpentFuel(double spentFuel) { - this.spentFuel = spentFuel; - } - - private double startOdometer; - - public double getStartOdometer() { - return startOdometer; - } - - public void setStartOdometer(double startOdometer) { - this.startOdometer = startOdometer; - } - private double endOdometer; - - public double getEndOdometer() { - return endOdometer; - } - - public void setEndOdometer(double endOdometer) { - this.endOdometer = endOdometer; - } - - private Date startTime; - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - private Date endTime; - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - -} diff --git a/src/main/java/org/traccar/reports/model/BaseReportItem.java b/src/main/java/org/traccar/reports/model/BaseReportItem.java new file mode 100644 index 000000000..6e270dfe3 --- /dev/null +++ b/src/main/java/org/traccar/reports/model/BaseReportItem.java @@ -0,0 +1,126 @@ +/* + * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.reports.model; + +import java.util.Date; + +public class BaseReportItem { + + private long deviceId; + + public long getDeviceId() { + return deviceId; + } + + public void setDeviceId(long deviceId) { + this.deviceId = deviceId; + } + + private String deviceName; + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + private double distance; + + public double getDistance() { + return distance; + } + + public void setDistance(double distance) { + this.distance = distance; + } + + public void addDistance(double distance) { + this.distance += distance; + } + + private double averageSpeed; + + public double getAverageSpeed() { + return averageSpeed; + } + + public void setAverageSpeed(double averageSpeed) { + this.averageSpeed = averageSpeed; + } + + private double maxSpeed; + + public double getMaxSpeed() { + return maxSpeed; + } + + public void setMaxSpeed(double maxSpeed) { + this.maxSpeed = maxSpeed; + } + + private double spentFuel; + + public double getSpentFuel() { + return spentFuel; + } + + public void setSpentFuel(double spentFuel) { + this.spentFuel = spentFuel; + } + + private double startOdometer; + + public double getStartOdometer() { + return startOdometer; + } + + public void setStartOdometer(double startOdometer) { + this.startOdometer = startOdometer; + } + private double endOdometer; + + public double getEndOdometer() { + return endOdometer; + } + + public void setEndOdometer(double endOdometer) { + this.endOdometer = endOdometer; + } + + private Date startTime; + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + private Date endTime; + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + +} diff --git a/src/main/java/org/traccar/reports/model/DeviceReport.java b/src/main/java/org/traccar/reports/model/DeviceReport.java deleted file mode 100644 index 932753d15..000000000 --- a/src/main/java/org/traccar/reports/model/DeviceReport.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class DeviceReport { - - private String deviceName; - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - private String groupName = ""; - - public String getGroupName() { - return groupName; - } - - public void setGroupName(String groupName) { - this.groupName = groupName; - } - - private List objects; - - public Collection getObjects() { - return objects; - } - - public void setObjects(Collection objects) { - this.objects = new ArrayList<>(objects); - } - -} diff --git a/src/main/java/org/traccar/reports/model/DeviceReportSection.java b/src/main/java/org/traccar/reports/model/DeviceReportSection.java new file mode 100644 index 000000000..ffc4d774f --- /dev/null +++ b/src/main/java/org/traccar/reports/model/DeviceReportSection.java @@ -0,0 +1,55 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.reports.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class DeviceReportSection { + + private String deviceName; + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + private String groupName = ""; + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + private List objects; + + public Collection getObjects() { + return objects; + } + + public void setObjects(Collection objects) { + this.objects = new ArrayList<>(objects); + } + +} diff --git a/src/main/java/org/traccar/reports/model/StopReport.java b/src/main/java/org/traccar/reports/model/StopReport.java deleted file mode 100644 index e20f2c503..000000000 --- a/src/main/java/org/traccar/reports/model/StopReport.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.reports.model; - -public class StopReport extends BaseReport { - - private long positionId; - - public long getPositionId() { - return positionId; - } - - public void setPositionId(long positionId) { - this.positionId = positionId; - } - - private double latitude; - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - private double longitude; - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - private String address; - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - private long duration; - - public long getDuration() { - return duration; - } - - public void setDuration(long duration) { - this.duration = duration; - } - - private long engineHours; // milliseconds - - public long getEngineHours() { - return engineHours; - } - - public void setEngineHours(long engineHours) { - this.engineHours = engineHours; - } -} diff --git a/src/main/java/org/traccar/reports/model/StopReportItem.java b/src/main/java/org/traccar/reports/model/StopReportItem.java new file mode 100644 index 000000000..3c35bdc21 --- /dev/null +++ b/src/main/java/org/traccar/reports/model/StopReportItem.java @@ -0,0 +1,80 @@ +/* + * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 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.reports.model; + +public class StopReportItem extends BaseReportItem { + + private long positionId; + + public long getPositionId() { + return positionId; + } + + public void setPositionId(long positionId) { + this.positionId = positionId; + } + + private double latitude; + + public double getLatitude() { + return latitude; + } + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + private double longitude; + + public double getLongitude() { + return longitude; + } + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + private String address; + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + private long duration; + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + private long engineHours; // milliseconds + + public long getEngineHours() { + return engineHours; + } + + public void setEngineHours(long engineHours) { + this.engineHours = engineHours; + } +} diff --git a/src/main/java/org/traccar/reports/model/SummaryReport.java b/src/main/java/org/traccar/reports/model/SummaryReport.java deleted file mode 100644 index 886f8b9e2..000000000 --- a/src/main/java/org/traccar/reports/model/SummaryReport.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 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.reports.model; - -public class SummaryReport extends BaseReport { - - private long engineHours; // milliseconds - - public long getEngineHours() { - return engineHours; - } - - public void setEngineHours(long engineHours) { - this.engineHours = engineHours; - } -} diff --git a/src/main/java/org/traccar/reports/model/SummaryReportItem.java b/src/main/java/org/traccar/reports/model/SummaryReportItem.java new file mode 100644 index 000000000..44a15cf1d --- /dev/null +++ b/src/main/java/org/traccar/reports/model/SummaryReportItem.java @@ -0,0 +1,30 @@ +/* + * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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.reports.model; + +public class SummaryReportItem extends BaseReportItem { + + private long engineHours; // milliseconds + + public long getEngineHours() { + return engineHours; + } + + public void setEngineHours(long engineHours) { + this.engineHours = engineHours; + } +} diff --git a/src/main/java/org/traccar/reports/model/TripReport.java b/src/main/java/org/traccar/reports/model/TripReport.java deleted file mode 100644 index 151c34bd5..000000000 --- a/src/main/java/org/traccar/reports/model/TripReport.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports.model; - -public class TripReport extends BaseReport { - - private long startPositionId; - - public long getStartPositionId() { - return startPositionId; - } - - public void setStartPositionId(long startPositionId) { - this.startPositionId = startPositionId; - } - - private long endPositionId; - - public long getEndPositionId() { - return endPositionId; - } - - public void setEndPositionId(long endPositionId) { - this.endPositionId = endPositionId; - } - - private double startLat; - - public double getStartLat() { - return startLat; - } - - public void setStartLat(double startLat) { - this.startLat = startLat; - } - - private double startLon; - - public double getStartLon() { - return startLon; - } - - public void setStartLon(double startLon) { - this.startLon = startLon; - } - - private double endLat; - - public double getEndLat() { - return endLat; - } - - public void setEndLat(double endLat) { - this.endLat = endLat; - } - - private double endLon; - - public double getEndLon() { - return endLon; - } - - public void setEndLon(double endLon) { - this.endLon = endLon; - } - - private String startAddress; - - public String getStartAddress() { - return startAddress; - } - - public void setStartAddress(String address) { - this.startAddress = address; - } - - private String endAddress; - - public String getEndAddress() { - return endAddress; - } - - public void setEndAddress(String address) { - this.endAddress = address; - } - - private long duration; - - public long getDuration() { - return duration; - } - - public void setDuration(long duration) { - this.duration = duration; - } - - private String driverUniqueId; - - public String getDriverUniqueId() { - return driverUniqueId; - } - - public void setDriverUniqueId(String driverUniqueId) { - this.driverUniqueId = driverUniqueId; - } - - private String driverName; - - public String getDriverName() { - return driverName; - } - - public void setDriverName(String driverName) { - this.driverName = driverName; - } -} diff --git a/src/main/java/org/traccar/reports/model/TripReportItem.java b/src/main/java/org/traccar/reports/model/TripReportItem.java new file mode 100644 index 000000000..332a34cca --- /dev/null +++ b/src/main/java/org/traccar/reports/model/TripReportItem.java @@ -0,0 +1,130 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.reports.model; + +public class TripReportItem extends BaseReportItem { + + private long startPositionId; + + public long getStartPositionId() { + return startPositionId; + } + + public void setStartPositionId(long startPositionId) { + this.startPositionId = startPositionId; + } + + private long endPositionId; + + public long getEndPositionId() { + return endPositionId; + } + + public void setEndPositionId(long endPositionId) { + this.endPositionId = endPositionId; + } + + private double startLat; + + public double getStartLat() { + return startLat; + } + + public void setStartLat(double startLat) { + this.startLat = startLat; + } + + private double startLon; + + public double getStartLon() { + return startLon; + } + + public void setStartLon(double startLon) { + this.startLon = startLon; + } + + private double endLat; + + public double getEndLat() { + return endLat; + } + + public void setEndLat(double endLat) { + this.endLat = endLat; + } + + private double endLon; + + public double getEndLon() { + return endLon; + } + + public void setEndLon(double endLon) { + this.endLon = endLon; + } + + private String startAddress; + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String address) { + this.startAddress = address; + } + + private String endAddress; + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String address) { + this.endAddress = address; + } + + private long duration; + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + private String driverUniqueId; + + public String getDriverUniqueId() { + return driverUniqueId; + } + + public void setDriverUniqueId(String driverUniqueId) { + this.driverUniqueId = driverUniqueId; + } + + private String driverName; + + public String getDriverName() { + return driverName; + } + + public void setDriverName(String driverName) { + this.driverName = driverName; + } +} diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 247e43499..e947a9afa 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -6,8 +6,8 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.StopReportItem; +import org.traccar.reports.model.TripReportItem; import org.traccar.reports.common.TripsConfig; import java.text.DateFormat; @@ -93,13 +93,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); @@ -108,15 +108,15 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - Iterator iterator = stops.iterator(); + Iterator iterator = stops.iterator(); - StopReport itemStop = iterator.next(); + StopReportItem itemStop = iterator.next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); @@ -147,13 +147,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); @@ -163,7 +163,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -177,15 +177,15 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - Iterator iterator = stops.iterator(); + Iterator iterator = stops.iterator(); - StopReport itemStop = iterator.next(); + StopReportItem itemStop = iterator.next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); @@ -218,13 +218,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:09:00.000"), itemTrip.getEndTime()); @@ -233,15 +233,15 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - Iterator iterator = stops.iterator(); + Iterator iterator = stops.iterator(); - StopReport itemStop = iterator.next(); + StopReportItem itemStop = iterator.next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); @@ -268,13 +268,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = result.iterator().next(); + StopReportItem itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); @@ -295,13 +295,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = result.iterator().next(); + StopReportItem itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getEndTime()); @@ -322,13 +322,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = result.iterator().next(); + StopReportItem itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); @@ -349,8 +349,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -372,13 +372,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemTrip.getEndTime()); @@ -387,13 +387,13 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - StopReport itemStop = stops.iterator().next(); + StopReportItem itemStop = stops.iterator().next(); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:24:00.000"), itemStop.getEndTime()); -- cgit v1.2.3 From 31c4ad41f4d91dec3c98af06614e9518d3689a14 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 11:01:01 -0700 Subject: Inject report providers --- .../org/traccar/api/resource/ReportResource.java | 46 ++++-- src/main/java/org/traccar/reports/Events.java | 136 ------------------ .../org/traccar/reports/EventsReportProvider.java | 133 +++++++++++++++++ src/main/java/org/traccar/reports/Route.java | 86 ----------- .../org/traccar/reports/RouteReportProvider.java | 83 +++++++++++ src/main/java/org/traccar/reports/Stops.java | 103 -------------- .../org/traccar/reports/StopsReportProvider.java | 100 +++++++++++++ src/main/java/org/traccar/reports/Summary.java | 157 --------------------- .../org/traccar/reports/SummaryReportProvider.java | 155 ++++++++++++++++++++ src/main/java/org/traccar/reports/Trips.java | 101 ------------- .../org/traccar/reports/TripsReportProvider.java | 98 +++++++++++++ 11 files changed, 600 insertions(+), 598 deletions(-) delete mode 100644 src/main/java/org/traccar/reports/Events.java create mode 100644 src/main/java/org/traccar/reports/EventsReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Route.java create mode 100644 src/main/java/org/traccar/reports/RouteReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Stops.java create mode 100644 src/main/java/org/traccar/reports/StopsReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Summary.java create mode 100644 src/main/java/org/traccar/reports/SummaryReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Trips.java create mode 100644 src/main/java/org/traccar/reports/TripsReportProvider.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 5346df31b..38eb52685 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -23,6 +23,7 @@ import java.util.Date; import java.util.List; import javax.activation.DataHandler; +import javax.inject.Inject; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.util.ByteArrayDataSource; @@ -43,14 +44,14 @@ import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; -import org.traccar.reports.Events; -import org.traccar.reports.Summary; -import org.traccar.reports.Trips; +import org.traccar.reports.EventsReportProvider; +import org.traccar.reports.SummaryReportProvider; +import org.traccar.reports.TripsReportProvider; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.SummaryReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.reports.Route; -import org.traccar.reports.Stops; +import org.traccar.reports.RouteReportProvider; +import org.traccar.reports.StopsReportProvider; import org.traccar.storage.StorageException; @Path("reports") @@ -63,6 +64,21 @@ public class ReportResource extends BaseResource { private static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; private static final String CONTENT_DISPOSITION_VALUE_XLSX = "attachment; filename=report.xlsx"; + @Inject + private EventsReportProvider eventsReportProvider; + + @Inject + private RouteReportProvider routeReportProvider; + + @Inject + private StopsReportProvider stopsReportProvider; + + @Inject + private SummaryReportProvider summaryReportProvider; + + @Inject + private TripsReportProvider tripsReportProvider; + private interface ReportExecutor { void execute(ByteArrayOutputStream stream) throws StorageException, IOException; } @@ -102,7 +118,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); - return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); + return routeReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); } @Path("route") @@ -115,7 +131,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); - Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); + routeReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); }); } @@ -127,7 +143,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - return Events.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); + return eventsReportProvider.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); } @Path("events") @@ -141,7 +157,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - Events.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); + eventsReportProvider.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); }); } @@ -153,7 +169,7 @@ public class ReportResource extends BaseResource { throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); - return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); + return summaryReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); } @Path("summary") @@ -167,7 +183,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); - Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); + summaryReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); }); } @@ -179,7 +195,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); - return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); + return tripsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); } @Path("trips") @@ -192,7 +208,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); - Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); + tripsReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); }); } @@ -204,7 +220,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); - return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); + return stopsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); } @Path("stops") @@ -217,7 +233,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); - Stops.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); + stopsReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); }); } diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java deleted file mode 100644 index 130fba724..000000000 --- a/src/main/java/org/traccar/reports/Events.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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"); - * 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Geofence; -import org.traccar.model.Group; -import org.traccar.model.Maintenance; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; - -public final class Events { - - private Events() { - } - - public static Collection getObjects( - Storage storage, long userId, - Collection deviceIds, Collection groupIds, - Collection types, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); - boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); - for (Event event : events) { - if (all || types.contains(event.getType())) { - long geofenceId = event.getGeofenceId(); - long maintenanceId = event.getMaintenanceId(); - if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) - && (maintenanceId == 0 - || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { - result.add(event); - } - } - } - } - return result; - } - - public static void getExcel( - OutputStream outputStream, Storage storage, long userId, - Collection deviceIds, Collection groupIds, - Collection types, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesEvents = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - HashMap geofenceNames = new HashMap<>(); - HashMap maintenanceNames = new HashMap<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); - boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); - for (Iterator iterator = events.iterator(); iterator.hasNext();) { - Event event = iterator.next(); - if (all || types.contains(event.getType())) { - long geofenceId = event.getGeofenceId(); - long maintenanceId = event.getMaintenanceId(); - if (geofenceId != 0) { - Geofence geofence = ReportUtils.getObject( - storage, userId, Geofence.class, geofenceId); - if (geofence != null) { - geofenceNames.put(geofenceId, geofence.getName()); - } else { - iterator.remove(); - } - } else if (maintenanceId != 0) { - Maintenance maintenance = ReportUtils.getObject( - storage, userId, Maintenance.class, maintenanceId); - if (maintenance != null) { - maintenanceNames.put(maintenanceId, maintenance.getName()); - } else { - iterator.remove(); - } - } - } else { - iterator.remove(); - } - } - DeviceReportSection deviceEvents = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceEvents.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceEvents.setGroupName(group.getName()); - } - } - deviceEvents.setObjects(events); - devicesEvents.add(deviceEvents); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesEvents); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("geofenceNames", geofenceNames); - jxlsContext.putVar("maintenanceNames", maintenanceNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java new file mode 100644 index 000000000..c4b0aad86 --- /dev/null +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -0,0 +1,133 @@ +/* + * 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"); + * 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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Group; +import org.traccar.model.Maintenance; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; + +public class EventsReportProvider { + + public Collection getObjects( + Storage storage, long userId, + Collection deviceIds, Collection groupIds, + Collection types, Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection events = Context.getDataManager().getEvents(deviceId, from, to); + boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); + for (Event event : events) { + if (all || types.contains(event.getType())) { + long geofenceId = event.getGeofenceId(); + long maintenanceId = event.getMaintenanceId(); + if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) + && (maintenanceId == 0 + || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { + result.add(event); + } + } + } + } + return result; + } + + public void getExcel( + OutputStream outputStream, Storage storage, long userId, + Collection deviceIds, Collection groupIds, + Collection types, Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesEvents = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + HashMap geofenceNames = new HashMap<>(); + HashMap maintenanceNames = new HashMap<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection events = Context.getDataManager().getEvents(deviceId, from, to); + boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); + for (Iterator iterator = events.iterator(); iterator.hasNext();) { + Event event = iterator.next(); + if (all || types.contains(event.getType())) { + long geofenceId = event.getGeofenceId(); + long maintenanceId = event.getMaintenanceId(); + if (geofenceId != 0) { + Geofence geofence = ReportUtils.getObject( + storage, userId, Geofence.class, geofenceId); + if (geofence != null) { + geofenceNames.put(geofenceId, geofence.getName()); + } else { + iterator.remove(); + } + } else if (maintenanceId != 0) { + Maintenance maintenance = ReportUtils.getObject( + storage, userId, Maintenance.class, maintenanceId); + if (maintenance != null) { + maintenanceNames.put(maintenanceId, maintenance.getName()); + } else { + iterator.remove(); + } + } + } else { + iterator.remove(); + } + } + DeviceReportSection deviceEvents = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceEvents.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceEvents.setGroupName(group.getName()); + } + } + deviceEvents.setObjects(events); + devicesEvents.add(deviceEvents); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesEvents); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("geofenceNames", geofenceNames); + jxlsContext.putVar("maintenanceNames", maintenanceNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } +} diff --git a/src/main/java/org/traccar/reports/Route.java b/src/main/java/org/traccar/reports/Route.java deleted file mode 100644 index 5b8629aad..000000000 --- a/src/main/java/org/traccar/reports/Route.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Position; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.storage.StorageException; - -public final class Route { - - private Route() { - } - - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesRoutes = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection positions = Context.getDataManager() - .getPositions(deviceId, from, to); - DeviceReportSection deviceRoutes = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceRoutes.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceRoutes.setGroupName(group.getName()); - } - } - deviceRoutes.setObjects(positions); - devicesRoutes.add(deviceRoutes); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesRoutes); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java new file mode 100644 index 000000000..4c4a41405 --- /dev/null +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -0,0 +1,83 @@ +/* + * 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"); + * 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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.StorageException; + +public class RouteReportProvider { + + public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); + } + return result; + } + + public void getExcel(OutputStream outputStream, + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesRoutes = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection positions = Context.getDataManager() + .getPositions(deviceId, from, to); + DeviceReportSection deviceRoutes = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceRoutes.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceRoutes.setGroupName(group.getName()); + } + } + deviceRoutes.setObjects(positions); + devicesRoutes.add(deviceRoutes); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesRoutes); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } +} diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java deleted file mode 100644 index e688d53da..000000000 --- a/src/main/java/org/traccar/reports/Stops.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.reports.model.StopReportItem; -import org.traccar.storage.StorageException; - -public final class Stops { - - private Stops() { - } - - private static Collection detectStops(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); - } - - public static Collection getObjects( - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(detectStops(deviceId, from, to)); - } - return result; - } - - public static void getExcel( - OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesStops = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection stops = detectStops(deviceId, from, to); - DeviceReportSection deviceStops = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceStops.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceStops.setGroupName(group.getName()); - } - } - deviceStops.setObjects(stops); - devicesStops.add(deviceStops); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesStops); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } - -} diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java new file mode 100644 index 000000000..8dedb9a24 --- /dev/null +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -0,0 +1,100 @@ +/* + * 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"); + * 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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.Main; +import org.traccar.database.DeviceManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.StopReportItem; +import org.traccar.storage.StorageException; + +public class StopsReportProvider { + + private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { + boolean ignoreOdometer = Context.getDeviceManager() + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + + IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); + DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); + + return ReportUtils.detectTripsAndStops( + identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); + } + + public Collection getObjects( + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + result.addAll(detectStops(deviceId, from, to)); + } + return result; + } + + public void getExcel( + OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesStops = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection stops = detectStops(deviceId, from, to); + DeviceReportSection deviceStops = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceStops.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceStops.setGroupName(group.getName()); + } + } + deviceStops.setObjects(stops); + devicesStops.add(deviceStops); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesStops); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } + +} diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java deleted file mode 100644 index 30c4cb057..000000000 --- a/src/main/java/org/traccar/reports/Summary.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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"); - * 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; - -import org.jxls.util.JxlsHelper; -import org.traccar.Context; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.SummaryReportItem; -import org.traccar.storage.StorageException; - -public final class Summary { - - private Summary() { - } - - private static SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { - SummaryReportItem result = new SummaryReportItem(); - result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); - if (positions != null && !positions.isEmpty()) { - Position firstPosition = null; - Position previousPosition = null; - for (Position position : positions) { - if (firstPosition == null) { - firstPosition = position; - } - previousPosition = position; - if (position.getSpeed() > result.getMaxSpeed()) { - result.setMaxSpeed(position.getSpeed()); - } - } - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); - result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); - - long durationMilliseconds; - if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) - && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) { - durationMilliseconds = - previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS); - result.setEngineHours(durationMilliseconds); - } else { - durationMilliseconds = - previousPosition.getFixTime().getTime() - firstPosition.getFixTime().getTime(); - } - - if (durationMilliseconds > 0) { - result.setAverageSpeed( - UnitsConverter.knotsFromMps(result.getDistance() * 1000 / durationMilliseconds)); - } - - if (!ignoreOdometer - && firstPosition.getDouble(Position.KEY_ODOMETER) != 0 - && previousPosition.getDouble(Position.KEY_ODOMETER) != 0) { - result.setStartOdometer(firstPosition.getDouble(Position.KEY_ODOMETER)); - result.setEndOdometer(previousPosition.getDouble(Position.KEY_ODOMETER)); - } else { - result.setStartOdometer(firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); - result.setEndOdometer(previousPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - result.setStartTime(firstPosition.getFixTime()); - result.setEndTime(previousPosition.getFixTime()); - } - return result; - } - - private static int getDay(long userId, Date date) { - Calendar calendar = Calendar.getInstance(ReportUtils.getTimezone(userId)); - calendar.setTime(date); - return calendar.get(Calendar.DAY_OF_MONTH); - } - - private static Collection calculateSummaryResults( - long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { - - ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); - - ArrayList results = new ArrayList<>(); - if (daily && !positions.isEmpty()) { - int startIndex = 0; - int startDay = getDay(userId, positions.iterator().next().getFixTime()); - for (int i = 0; i < positions.size(); i++) { - int currentDay = getDay(userId, positions.get(i).getFixTime()); - if (currentDay != startDay) { - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, i))); - startIndex = i; - startDay = currentDay; - } - } - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, positions.size()))); - } else { - results.add(calculateSummaryResult(deviceId, positions)); - } - - return results; - } - - public static Collection getObjects(long userId, Collection deviceIds, - Collection groupIds, Date from, Date to, boolean daily) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); - for (SummaryReportItem summaryReport : deviceResults) { - if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { - result.add(summaryReport); - } - } - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to, boolean daily) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("summaries", summaries); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - JxlsHelper.getInstance().setUseFastFormulaProcessor(false) - .processTemplate(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java new file mode 100644 index 000000000..a2306f3d1 --- /dev/null +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -0,0 +1,155 @@ +/* + * 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"); + * 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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; + +import org.jxls.util.JxlsHelper; +import org.traccar.Context; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.SummaryReportItem; +import org.traccar.storage.StorageException; + +public class SummaryReportProvider { + + private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { + SummaryReportItem result = new SummaryReportItem(); + result.setDeviceId(deviceId); + result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + if (positions != null && !positions.isEmpty()) { + Position firstPosition = null; + Position previousPosition = null; + for (Position position : positions) { + if (firstPosition == null) { + firstPosition = position; + } + previousPosition = position; + if (position.getSpeed() > result.getMaxSpeed()) { + result.setMaxSpeed(position.getSpeed()); + } + } + boolean ignoreOdometer = Context.getDeviceManager() + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); + result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); + + long durationMilliseconds; + if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) + && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) { + durationMilliseconds = + previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS); + result.setEngineHours(durationMilliseconds); + } else { + durationMilliseconds = + previousPosition.getFixTime().getTime() - firstPosition.getFixTime().getTime(); + } + + if (durationMilliseconds > 0) { + result.setAverageSpeed( + UnitsConverter.knotsFromMps(result.getDistance() * 1000 / durationMilliseconds)); + } + + if (!ignoreOdometer + && firstPosition.getDouble(Position.KEY_ODOMETER) != 0 + && previousPosition.getDouble(Position.KEY_ODOMETER) != 0) { + result.setStartOdometer(firstPosition.getDouble(Position.KEY_ODOMETER)); + result.setEndOdometer(previousPosition.getDouble(Position.KEY_ODOMETER)); + } else { + result.setStartOdometer(firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); + result.setEndOdometer(previousPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + + result.setStartTime(firstPosition.getFixTime()); + result.setEndTime(previousPosition.getFixTime()); + } + return result; + } + + private int getDay(long userId, Date date) { + Calendar calendar = Calendar.getInstance(ReportUtils.getTimezone(userId)); + calendar.setTime(date); + return calendar.get(Calendar.DAY_OF_MONTH); + } + + private Collection calculateSummaryResults( + long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { + + ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); + + ArrayList results = new ArrayList<>(); + if (daily && !positions.isEmpty()) { + int startIndex = 0; + int startDay = getDay(userId, positions.iterator().next().getFixTime()); + for (int i = 0; i < positions.size(); i++) { + int currentDay = getDay(userId, positions.get(i).getFixTime()); + if (currentDay != startDay) { + results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, i))); + startIndex = i; + startDay = currentDay; + } + } + results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, positions.size()))); + } else { + results.add(calculateSummaryResult(deviceId, positions)); + } + + return results; + } + + public Collection getObjects( + long userId, Collection deviceIds, + Collection groupIds, Date from, Date to, boolean daily) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (SummaryReportItem summaryReport : deviceResults) { + if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { + result.add(summaryReport); + } + } + } + return result; + } + + public void getExcel(OutputStream outputStream, + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to, boolean daily) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("summaries", summaries); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + JxlsHelper.getInstance().setUseFastFormulaProcessor(false) + .processTemplate(inputStream, outputStream, jxlsContext); + } + } +} diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java deleted file mode 100644 index 74e24cf2f..000000000 --- a/src/main/java/org/traccar/reports/Trips.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.reports.model.TripReportItem; -import org.traccar.storage.StorageException; - -public final class Trips { - - private Trips() { - } - - private static Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); - } - - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(detectTrips(deviceId, from, to)); - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesTrips = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection trips = detectTrips(deviceId, from, to); - DeviceReportSection deviceTrips = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceTrips.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceTrips.setGroupName(group.getName()); - } - } - deviceTrips.setObjects(trips); - devicesTrips.add(deviceTrips); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesTrips); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } - -} diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java new file mode 100644 index 000000000..6aff08a1d --- /dev/null +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -0,0 +1,98 @@ +/* + * 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"); + * 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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.Main; +import org.traccar.database.DeviceManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.TripReportItem; +import org.traccar.storage.StorageException; + +public class TripsReportProvider { + + private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { + boolean ignoreOdometer = Context.getDeviceManager() + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + + IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); + DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); + + return ReportUtils.detectTripsAndStops( + identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); + } + + public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + result.addAll(detectTrips(deviceId, from, to)); + } + return result; + } + + public void getExcel(OutputStream outputStream, + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesTrips = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection trips = detectTrips(deviceId, from, to); + DeviceReportSection deviceTrips = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceTrips.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceTrips.setGroupName(group.getName()); + } + } + deviceTrips.setObjects(trips); + devicesTrips.add(deviceTrips); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesTrips); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } + +} -- cgit v1.2.3 From e41c234ae93c6cc1b43f1e78af8566f288e0c10e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 11:02:22 -0700 Subject: Inject storage for events report --- .../java/org/traccar/reports/EventsReportProvider.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index c4b0aad86..9b4a7df2b 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -38,11 +38,19 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class EventsReportProvider { + private final Storage storage; + + @Inject + public EventsReportProvider(Storage storage) { + this.storage = storage; + } + public Collection getObjects( - Storage storage, long userId, - Collection deviceIds, Collection groupIds, + long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); @@ -66,8 +74,7 @@ public class EventsReportProvider { } public void getExcel( - OutputStream outputStream, Storage storage, long userId, - Collection deviceIds, Collection groupIds, + OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesEvents = new ArrayList<>(); -- cgit v1.2.3 From b6ec84dbb4e1e2e212b0d6195920407a43919ab5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 11:03:59 -0700 Subject: Fix compilation issue --- src/main/java/org/traccar/api/resource/ReportResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 38eb52685..96b32a4f0 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -143,7 +143,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - return eventsReportProvider.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); + return eventsReportProvider.getObjects(getUserId(), deviceIds, groupIds, types, from, to); } @Path("events") @@ -157,7 +157,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - eventsReportProvider.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); + eventsReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); }); } -- cgit v1.2.3 From 3b5c04b4ddf71223371815575fa1b652fea1d5da Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 20:15:03 -0700 Subject: Handle modern app paths --- src/main/java/org/traccar/web/WebServer.java | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 0ed5d013e..9af9fd33a 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -68,16 +68,17 @@ import java.io.File; import java.io.IOException; import java.io.Writer; import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.EnumSet; public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); - private Server server; - - private void initServer(Config config) { + private final Server server; + public WebServer(Config config) { String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); if (address == null) { @@ -85,11 +86,6 @@ public class WebServer implements LifecycleObject { } else { server = new Server(new InetSocketAddress(address, port)); } - } - - public WebServer(Config config) { - - initServer(config); ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); @@ -106,8 +102,13 @@ public class WebServer implements LifecycleObject { @Override protected void handleErrorPage( HttpServletRequest request, Writer writer, int code, String message) throws IOException { - writer.write("Error" - + code + " - " + HttpStatus.getMessage(code) + ""); + if (code == HttpStatus.NOT_FOUND_404 && request.getPathInfo().startsWith("/modern")) { + writer.write(Files.readString( + Paths.get(config.getString(Keys.WEB_PATH), "modern", "index.html"))); + } else { + writer.write("Error" + + code + " - " + HttpStatus.getMessage(code) + ""); + } } }); -- cgit v1.2.3 From 59bbaa37656d1aacd7df21d70ec5bfa85cf98608 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 6 Jun 2022 19:05:20 -0700 Subject: Handle missing cache (fix #4861) --- src/main/java/org/traccar/session/cache/CacheManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index aca3df52d..102a31ecd 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -69,7 +69,8 @@ public class CacheManager { public T getObject(Class clazz, long id) { try { lock.readLock().lock(); - return deviceCache.get(new CacheKey(clazz, id)).getValue(); + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + return cacheValue != null ? cacheValue.getValue() : null; } finally { lock.readLock().unlock(); } -- cgit v1.2.3 From 669bdccecff50eaca46c815598df092ad0fe143d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 6 Jun 2022 19:19:48 -0700 Subject: Simplify logs config --- src/main/java/org/traccar/config/Keys.java | 7 ------- src/main/java/org/traccar/web/WebServer.java | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index f5370874d..ba576397b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1198,13 +1198,6 @@ public final class Keys { "location.longitudeHemisphere", Collections.singletonList(KeyType.GLOBAL)); - /** - * Enable Jetty Request Log. - */ - public static final ConfigKey WEB_REQUEST_LOG_ENABLE = new ConfigKey<>( - "web.requestLog.enable", - Collections.singletonList(KeyType.GLOBAL)); - /** * Jetty Request Log Path. * The path must include the string "yyyy_mm_dd", which is replaced with the actual date when creating and rolling diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 9af9fd33a..06676fb41 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -118,7 +118,7 @@ public class WebServer implements LifecycleObject { handlers.addHandler(new GzipHandler()); server.setHandler(handlers); - if (config.getBoolean(Keys.WEB_REQUEST_LOG_ENABLE)) { + if (config.hasKey(Keys.WEB_REQUEST_LOG_PATH)) { RequestLogWriter logWriter = new RequestLogWriter(config.getString(Keys.WEB_REQUEST_LOG_PATH)); logWriter.setAppend(true); logWriter.setRetainDays(config.getInteger(Keys.WEB_REQUEST_LOG_RETAIN_DAYS)); -- cgit v1.2.3 From 8eecfdcf5c59f92158a6c339d1622e0e9d67968c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 06:48:53 -0700 Subject: Pass user to notificators --- .../java/org/traccar/api/resource/NotificationResource.java | 12 ++++++++---- src/main/java/org/traccar/api/resource/PasswordResource.java | 2 +- src/main/java/org/traccar/api/resource/ReportResource.java | 4 +++- .../java/org/traccar/api/security/PermissionsService.java | 4 ++-- src/main/java/org/traccar/database/MailManager.java | 10 ++++------ src/main/java/org/traccar/database/NotificationManager.java | 4 +++- .../java/org/traccar/notification/NotificationFormatter.java | 9 ++++----- src/main/java/org/traccar/notificators/Notificator.java | 9 +++++---- .../java/org/traccar/notificators/NotificatorFirebase.java | 11 +++++------ src/main/java/org/traccar/notificators/NotificatorMail.java | 9 +++++---- src/main/java/org/traccar/notificators/NotificatorNull.java | 7 ++++--- .../java/org/traccar/notificators/NotificatorPushover.java | 12 +++++------- src/main/java/org/traccar/notificators/NotificatorSms.java | 12 +++++------- .../java/org/traccar/notificators/NotificatorTelegram.java | 11 +++++------ src/main/java/org/traccar/notificators/NotificatorWeb.java | 7 ++++--- 15 files changed, 63 insertions(+), 60 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index cf4b66fa1..2fc103e20 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -31,7 +31,9 @@ import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Event; import org.traccar.model.Notification; import org.traccar.model.Typed; +import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.storage.StorageException; @Path("notifications") @Produces(MediaType.APPLICATION_JSON) @@ -56,10 +58,11 @@ public class NotificationResource extends ExtendedObjectResource { @POST @Path("test") - public Response testMessage() throws MessageException, InterruptedException { + public Response testMessage() throws MessageException, InterruptedException, StorageException { + User user = permissionsService.getUser(getUserId()); for (Typed method : Context.getNotificatorManager().getAllNotificatorTypes()) { Context.getNotificatorManager() - .getNotificator(method.getType()).sendSync(getUserId(), new Event("test", 0), null); + .getNotificator(method.getType()).sendSync(user, new Event("test", 0), null); } return Response.noContent().build(); } @@ -67,8 +70,9 @@ public class NotificationResource extends ExtendedObjectResource { @POST @Path("test/{notificator}") public Response testMessage(@PathParam("notificator") String notificator) - throws MessageException, InterruptedException { - Context.getNotificatorManager().getNotificator(notificator).sendSync(getUserId(), new Event("test", 0), null); + throws MessageException, InterruptedException, StorageException { + User user = permissionsService.getUser(getUserId()); + Context.getNotificatorManager().getNotificator(notificator).sendSync(user, new Event("test", 0), null); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 0642ff3cc..ed7131718 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -55,7 +55,7 @@ public class PasswordResource extends BaseResource { velocityContext.put("token", token); NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); + Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); break; } } diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 96b32a4f0..3c1b8f715 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -43,6 +43,7 @@ import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.reports.EventsReportProvider; import org.traccar.reports.SummaryReportProvider; @@ -97,8 +98,9 @@ public class ReportResource extends BaseResource { attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( stream.toByteArray(), "application/octet-stream"))); + User user = permissionsService.getUser(userId); Context.getMailManager().sendMessage( - userId, "Report", "The report is in the attachment.", attachment); + user, "Report", "The report is in the attachment.", attachment); } catch (StorageException | IOException | MessagingException e) { LOGGER.warn("Report failed", e); } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 12a2189e9..9ec3b43c1 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -46,7 +46,7 @@ public class PermissionsService { this.storage = storage; } - private Server getServer() throws StorageException { + public Server getServer() throws StorageException { if (server == null) { server = storage.getObject( Server.class, new Request(new Columns.All())); @@ -54,7 +54,7 @@ public class PermissionsService { return server; } - private User getUser(long userId) throws StorageException { + public User getUser(long userId) throws StorageException { if (user == null) { user = storage.getObject( User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index d94f55cda..21fee5ee7 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -92,14 +92,12 @@ public final class MailManager { } public void sendMessage( - long userId, String subject, String body) throws MessagingException { - sendMessage(userId, subject, body, null); + User user, String subject, String body) throws MessagingException { + sendMessage(user, subject, body, null); } public void sendMessage( - long userId, String subject, String body, MimeBodyPart attachment) throws MessagingException { - User user = Context.getPermissionsManager().getUser(userId); - + User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { Properties properties = null; if (!Context.getConfig().getBoolean("mail.smtp.ignoreUserConfig")) { properties = getProperties(new PropertiesProvider(user)); diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 64f3b6775..f88b3b18c 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -35,6 +35,7 @@ import org.traccar.model.Event; import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.Typed; +import org.traccar.model.User; import org.traccar.storage.StorageException; public class NotificationManager extends ExtendedObjectManager { @@ -106,8 +107,9 @@ public class NotificationManager extends ExtendedObjectManager { .getAddress(position.getLatitude(), position.getLongitude(), null)); } + User user = Context.getUsersManager().getById(userId); for (String notificator : notificators) { - Context.getNotificatorManager().getNotificator(notificator).sendAsync(userId, event, position); + Context.getNotificatorManager().getNotificator(notificator).sendAsync(user, event, position); } } if (Context.getEventForwarder() != null) { diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 30a862372..c3e37c9e9 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -33,9 +33,8 @@ public final class NotificationFormatter { } public static NotificationMessage formatMessage( - CacheManager cacheManager, long userId, Event event, Position position, String templatePath) { + CacheManager cacheManager, User user, Event event, Position position, String templatePath) { - User user = cacheManager.getObject(User.class, userId); Device device = cacheManager.getObject(Device.class, event.getDeviceId()); VelocityContext velocityContext = TextTemplateFormatter.prepareContext(user); @@ -44,9 +43,9 @@ public final class NotificationFormatter { velocityContext.put("event", event); if (position != null) { velocityContext.put("position", position); - velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(userId)); - velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(userId)); - velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(userId)); + velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(user.getId())); + velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(user.getId())); + velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(user.getId())); } if (event.getGeofenceId() != 0) { velocityContext.put("geofence", cacheManager.getObject(Geofence.class, event.getGeofenceId())); diff --git a/src/main/java/org/traccar/notificators/Notificator.java b/src/main/java/org/traccar/notificators/Notificator.java index dd888bae9..3903f3008 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 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"); @@ -20,23 +20,24 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.MessageException; public abstract class Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(Notificator.class); - public void sendAsync(final long userId, final Event event, final Position position) { + public void sendAsync(User user, Event event, Position position) { new Thread(() -> { try { - sendSync(userId, event, position); + sendSync(user, event, position); } catch (MessageException | InterruptedException error) { LOGGER.warn("Event send error", error); } }).start(); } - public abstract void sendSync(long userId, Event event, Position position) + public abstract void sendSync(User user, Event event, Position position) throws MessageException, InterruptedException; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index bcce9a4d8..ee22b3a22 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 - 2020 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"); @@ -67,12 +67,11 @@ public class NotificatorFirebase extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) { - final User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); @@ -99,8 +98,8 @@ public class NotificatorFirebase extends Notificator { } @Override - public void sendAsync(long userId, Event event, Position position) { - sendSync(userId, event, position); + public void sendAsync(User user, Event event, Position position) { + sendSync(user, event, position); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index eb7f399eb..7b85254be 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 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ import org.traccar.Context; import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.NotificationMessage; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; @@ -30,11 +31,11 @@ import javax.mail.MessagingException; public final class NotificatorMail extends Notificator { @Override - public void sendSync(long userId, Event event, Position position) throws MessageException { + public void sendSync(User user, Event event, Position position) throws MessageException { try { NotificationMessage fullMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "full"); - Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "full"); + Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); } diff --git a/src/main/java/org/traccar/notificators/NotificatorNull.java b/src/main/java/org/traccar/notificators/NotificatorNull.java index 9364336be..a03a6e2c9 100644 --- a/src/main/java/org/traccar/notificators/NotificatorNull.java +++ b/src/main/java/org/traccar/notificators/NotificatorNull.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 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"); @@ -20,18 +20,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; public final class NotificatorNull extends Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorNull.class); @Override - public void sendAsync(long userId, Event event, Position position) { + public void sendAsync(User user, Event event, Position position) { LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); } @Override - public void sendSync(long userId, Event event, Position position) { + public void sendSync(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 73fad9bd2..ffd9b426f 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 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. @@ -59,9 +59,7 @@ public class NotificatorPushover extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) { - - final User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) { String device = ""; @@ -80,7 +78,7 @@ public class NotificatorPushover extends Notificator { } NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Message message = new Message(); message.token = token; @@ -103,8 +101,8 @@ public class NotificatorPushover extends Notificator { } @Override - public void sendAsync(long userId, Event event, Position position) { - sendSync(userId, event, position); + public void sendAsync(User user, Event event, Position position) { + sendSync(user, event, position); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 09eb65b0c..ae409c558 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 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,11 +30,10 @@ import org.traccar.session.cache.CacheManager; public final class NotificatorSms extends Notificator { @Override - public void sendAsync(long userId, Event event, Position position) { - final User user = Context.getPermissionsManager().getUser(userId); + public void sendAsync(User user, Event event, Position position) { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), shortMessage.getBody(), false); @@ -42,11 +41,10 @@ public final class NotificatorSms extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) throws MessageException, InterruptedException { - final User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), shortMessage.getBody(), false); diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index a8e69e77d..46e29559d 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 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2021 Rafael Miquelino (rafaelmiquelino@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -99,10 +99,9 @@ public class NotificatorTelegram extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) { - User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); @@ -117,8 +116,8 @@ public class NotificatorTelegram extends Notificator { } @Override - public void sendAsync(long userId, Event event, Position position) { - sendSync(userId, event, position); + public void sendAsync(User user, Event event, Position position) { + sendSync(user, event, position); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 1d11c0b46..c9ab93b6d 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 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"); @@ -19,12 +19,13 @@ package org.traccar.notificators; import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; public final class NotificatorWeb extends Notificator { @Override - public void sendSync(long userId, Event event, Position position) { - Context.getConnectionManager().updateEvent(userId, event); + public void sendSync(User user, Event event, Position position) { + Context.getConnectionManager().updateEvent(user.getId(), event); } } -- cgit v1.2.3 From 65f9e253171dc6805127e5279b97fad05f8c4b9f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 07:07:25 -0700 Subject: Remove async methods --- src/main/java/org/traccar/BaseProtocol.java | 4 +-- .../traccar/api/resource/NotificationResource.java | 4 +-- .../java/org/traccar/database/CommandsManager.java | 2 +- .../org/traccar/database/NotificationManager.java | 13 +++++++-- .../java/org/traccar/notificators/Notificator.java | 19 ++----------- .../traccar/notificators/NotificatorFirebase.java | 9 ++---- .../org/traccar/notificators/NotificatorMail.java | 4 +-- .../org/traccar/notificators/NotificatorNull.java | 9 ++---- .../traccar/notificators/NotificatorPushover.java | 9 ++---- .../org/traccar/notificators/NotificatorSms.java | 18 ++---------- .../traccar/notificators/NotificatorTelegram.java | 9 ++---- .../org/traccar/notificators/NotificatorWeb.java | 4 +-- src/main/java/org/traccar/sms/HttpSmsClient.java | 32 +++++----------------- src/main/java/org/traccar/sms/SmsManager.java | 7 ++--- src/main/java/org/traccar/sms/SnsSmsClient.java | 9 ++---- 15 files changed, 43 insertions(+), 109 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index 52d34dc44..ec1933dc8 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.java @@ -113,11 +113,11 @@ public abstract class BaseProtocol implements Protocol { public void sendTextCommand(String destAddress, Command command) throws Exception { if (Context.getSmsManager() != null) { if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmsManager().sendMessageSync(destAddress, command.getString(Command.KEY_DATA), true); + Context.getSmsManager().sendMessage(destAddress, command.getString(Command.KEY_DATA), true); } else if (supportedTextCommands.contains(command.getType()) && textCommandEncoder != null) { String encodedCommand = (String) textCommandEncoder.encodeCommand(command); if (encodedCommand != null) { - Context.getSmsManager().sendMessageSync(destAddress, encodedCommand, true); + Context.getSmsManager().sendMessage(destAddress, encodedCommand, true); } else { throw new RuntimeException("Failed to encode command"); } diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 2fc103e20..9ea811473 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -62,7 +62,7 @@ public class NotificationResource extends ExtendedObjectResource { User user = permissionsService.getUser(getUserId()); for (Typed method : Context.getNotificatorManager().getAllNotificatorTypes()) { Context.getNotificatorManager() - .getNotificator(method.getType()).sendSync(user, new Event("test", 0), null); + .getNotificator(method.getType()).send(user, new Event("test", 0), null); } return Response.noContent().build(); } @@ -72,7 +72,7 @@ public class NotificationResource extends ExtendedObjectResource { public Response testMessage(@PathParam("notificator") String notificator) throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); - Context.getNotificatorManager().getNotificator(notificator).sendSync(user, new Event("test", 0), null); + Context.getNotificatorManager().getNotificator(notificator).send(user, new Event("test", 0), null); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index d440755f7..8dd2ba8b7 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -79,7 +79,7 @@ public class CommandsManager { BaseProtocol protocol = serverManager.getProtocol(position.getProtocol()); protocol.sendTextCommand(device.getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - smsManager.sendMessageSync(device.getPhone(), command.getString(Command.KEY_DATA), true); + smsManager.sendMessage(device.getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index f88b3b18c..2f912fff1 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -36,6 +36,7 @@ import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; +import org.traccar.notification.MessageException; import org.traccar.storage.StorageException; public class NotificationManager extends ExtendedObjectManager { @@ -108,9 +109,15 @@ public class NotificationManager extends ExtendedObjectManager { } User user = Context.getUsersManager().getById(userId); - for (String notificator : notificators) { - Context.getNotificatorManager().getNotificator(notificator).sendAsync(user, event, position); - } + new Thread(() -> { + for (String notificator : notificators) { + try { + Context.getNotificatorManager().getNotificator(notificator).send(user, event, position); + } catch (MessageException | InterruptedException exception) { + LOGGER.warn("Notification failed", exception); + } + } + }).start(); } if (Context.getEventForwarder() != null) { Context.getEventForwarder().forwardEvent(event, position, usersToForward); diff --git a/src/main/java/org/traccar/notificators/Notificator.java b/src/main/java/org/traccar/notificators/Notificator.java index 3903f3008..052365c7a 100644 --- a/src/main/java/org/traccar/notificators/Notificator.java +++ b/src/main/java/org/traccar/notificators/Notificator.java @@ -16,28 +16,13 @@ */ 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; import org.traccar.notification.MessageException; -public abstract class Notificator { +public interface Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(Notificator.class); - - public void sendAsync(User user, Event event, Position position) { - new Thread(() -> { - try { - sendSync(user, event, position); - } catch (MessageException | InterruptedException error) { - LOGGER.warn("Event send error", error); - } - }).start(); - } - - public abstract void sendSync(User user, Event event, Position position) - throws MessageException, InterruptedException; + void send(User user, Event event, Position position) throws MessageException, InterruptedException; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index ee22b3a22..cafd2237d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -32,7 +32,7 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; -public class NotificatorFirebase extends Notificator { +public class NotificatorFirebase implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorFirebase.class); @@ -67,7 +67,7 @@ public class NotificatorFirebase extends Notificator { } @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( @@ -97,9 +97,4 @@ public class NotificatorFirebase extends Notificator { } } - @Override - public void sendAsync(User user, Event event, Position position) { - sendSync(user, event, position); - } - } diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 7b85254be..fd7cae7c3 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -28,10 +28,10 @@ import org.traccar.session.cache.CacheManager; import javax.mail.MessagingException; -public final class NotificatorMail extends Notificator { +public final class NotificatorMail implements Notificator { @Override - public void sendSync(User user, Event event, Position position) throws MessageException { + public void send(User user, Event event, Position position) throws MessageException { try { NotificationMessage fullMessage = NotificationFormatter.formatMessage( Main.getInjector().getInstance(CacheManager.class), user, event, position, "full"); diff --git a/src/main/java/org/traccar/notificators/NotificatorNull.java b/src/main/java/org/traccar/notificators/NotificatorNull.java index a03a6e2c9..ba9ade9c6 100644 --- a/src/main/java/org/traccar/notificators/NotificatorNull.java +++ b/src/main/java/org/traccar/notificators/NotificatorNull.java @@ -22,17 +22,12 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -public final class NotificatorNull extends Notificator { +public class NotificatorNull implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorNull.class); @Override - public void sendAsync(User user, Event event, Position position) { - LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); - } - - @Override - public void sendSync(User user, Event event, Position position) { + 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 ffd9b426f..70c1a6cdc 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -31,7 +31,7 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; -public class NotificatorPushover extends Notificator { +public class NotificatorPushover implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorPushover.class); @@ -59,7 +59,7 @@ public class NotificatorPushover extends Notificator { } @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { String device = ""; @@ -100,9 +100,4 @@ public class NotificatorPushover extends Notificator { }); } - @Override - public void sendAsync(User user, Event event, Position position) { - sendSync(user, event, position); - } - } diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index ae409c558..f35b797cd 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -27,27 +27,15 @@ import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; -public final class NotificatorSms extends Notificator { +public final class NotificatorSms implements Notificator { @Override - public void sendAsync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - Context.getSmsManager().sendMessageAsync(user.getPhone(), - shortMessage.getBody(), false); - } - } - - @Override - public void sendSync(User user, Event event, Position position) throws MessageException, InterruptedException { - if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); - Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - Context.getSmsManager().sendMessageSync(user.getPhone(), - shortMessage.getBody(), false); + Context.getSmsManager().sendMessage(user.getPhone(), shortMessage.getBody(), false); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 46e29559d..0ed53ac4c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -32,7 +32,7 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; -public class NotificatorTelegram extends Notificator { +public class NotificatorTelegram implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorTelegram.class); @@ -99,7 +99,7 @@ public class NotificatorTelegram extends Notificator { } @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); @@ -115,9 +115,4 @@ public class NotificatorTelegram extends Notificator { } } - @Override - public void sendAsync(User user, Event event, Position position) { - sendSync(user, event, position); - } - } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index c9ab93b6d..023cb04af 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -21,10 +21,10 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -public final class NotificatorWeb extends Notificator { +public final class NotificatorWeb implements Notificator { @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { Context.getConnectionManager().updateEvent(user.getId(), event); } diff --git a/src/main/java/org/traccar/sms/HttpSmsClient.java b/src/main/java/org/traccar/sms/HttpSmsClient.java index 6234eabb8..5c3cef747 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 - 2020 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"); @@ -16,8 +16,6 @@ */ package org.traccar.sms; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; @@ -25,7 +23,6 @@ import org.traccar.notification.MessageException; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.InvocationCallback; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.UnsupportedEncodingException; @@ -34,8 +31,6 @@ import java.nio.charset.StandardCharsets; public class HttpSmsClient implements SmsManager { - private static final Logger LOGGER = LoggerFactory.getLogger(HttpSmsClient.class); - private final String url; private final String authorizationHeader; private final String authorization; @@ -91,26 +86,13 @@ public class HttpSmsClient implements SmsManager { } @Override - public void sendMessageSync(String destAddress, String message, boolean command) throws MessageException { - Response response = getRequestBuilder().post(Entity.entity(preparePayload(destAddress, message), mediaType)); - if (response.getStatus() / 100 != 2) { - throw new MessageException(response.readEntity(String.class)); - } - } - - @Override - public void sendMessageAsync(final String destAddress, final String message, final boolean command) { - getRequestBuilder().async().post( - Entity.entity(preparePayload(destAddress, message), mediaType), new InvocationCallback() { - @Override - public void completed(String s) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("SMS send failed", throwable); + public void sendMessage(String destAddress, String message, boolean command) throws MessageException { + try (Response response = getRequestBuilder() + .post(Entity.entity(preparePayload(destAddress, message), mediaType))) { + if (response.getStatus() / 100 != 2) { + throw new MessageException(response.readEntity(String.class)); } - }); + } } } diff --git a/src/main/java/org/traccar/sms/SmsManager.java b/src/main/java/org/traccar/sms/SmsManager.java index 3b0cbda7f..9ab25d9cb 100644 --- a/src/main/java/org/traccar/sms/SmsManager.java +++ b/src/main/java/org/traccar/sms/SmsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 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"); @@ -20,10 +20,7 @@ import org.traccar.notification.MessageException; public interface SmsManager { - void sendMessageSync( + void sendMessage( String destAddress, String message, boolean command) throws InterruptedException, MessageException; - void sendMessageAsync( - String destAddress, String message, boolean command); - } diff --git a/src/main/java/org/traccar/sms/SnsSmsClient.java b/src/main/java/org/traccar/sms/SnsSmsClient.java index bdd4104f5..49889ac89 100644 --- a/src/main/java/org/traccar/sms/SnsSmsClient.java +++ b/src/main/java/org/traccar/sms/SnsSmsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2021 Subodh Ranadive (subodhranadive3103@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -54,7 +54,7 @@ public class SnsSmsClient implements SmsManager { } @Override - public void sendMessageSync(String destAddress, String message, boolean command) { + public void sendMessage(String destAddress, String message, boolean command) { Map smsAttributes = new HashMap<>(); smsAttributes.put("AWS.SNS.SMS.SenderID", new MessageAttributeValue().withStringValue("SNS").withDataType("String")); @@ -74,9 +74,4 @@ public class SnsSmsClient implements SmsManager { } }); } - - @Override - public void sendMessageAsync(String destAddress, String message, boolean command) { - sendMessageSync(destAddress, message, command); - } } -- cgit v1.2.3 From 3a83acbf92741b34323a74bd1a233186d507c46b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 07:16:51 -0700 Subject: Send formatted event message --- .../org/traccar/notificators/NotificatorWeb.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 023cb04af..e19a94c1d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -17,15 +17,34 @@ package org.traccar.notificators; import org.traccar.Context; +import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.notification.NotificationFormatter; +import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; public final class NotificatorWeb implements Notificator { @Override public void send(User user, Event event, Position position) { - Context.getConnectionManager().updateEvent(user.getId(), event); + + Event copy = new Event(); + copy.setId(event.getId()); + copy.setDeviceId(event.getDeviceId()); + copy.setType(event.getType()); + copy.setEventTime(event.getEventTime()); + copy.setPositionId(event.getPositionId()); + copy.setGeofenceId(event.getGeofenceId()); + copy.setMaintenanceId(event.getMaintenanceId()); + copy.getAttributes().putAll(event.getAttributes()); + + NotificationMessage message = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + copy.set("message", message.getBody()); + + Context.getConnectionManager().updateEvent(user.getId(), copy); } } -- cgit v1.2.3 From 79cc136a4e8394cf340277ff2a912e97b89d5c59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 08:22:55 -0700 Subject: Remove calendar manager --- src/main/java/org/traccar/Context.java | 14 ++--------- src/main/java/org/traccar/MainModule.java | 6 ----- .../java/org/traccar/database/CalendarManager.java | 27 ---------------------- .../org/traccar/database/NotificationManager.java | 8 +++++-- .../org/traccar/database/PermissionsManager.java | 4 ---- .../handler/events/GeofenceEventHandler.java | 12 +++++----- 6 files changed, 14 insertions(+), 57 deletions(-) delete mode 100644 src/main/java/org/traccar/database/CalendarManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index dde98f505..e5a0c640f 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -24,7 +24,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; -import org.traccar.database.CalendarManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; @@ -39,7 +38,6 @@ import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -50,6 +48,7 @@ import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.reports.common.TripsConfig; import org.traccar.session.ConnectionManager; +import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -149,12 +148,6 @@ public final class Context { return geofenceManager; } - private static CalendarManager calendarManager; - - public static CalendarManager getCalendarManager() { - return calendarManager; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -291,8 +284,7 @@ public final class Context { private static void initEventsModule() { geofenceManager = new GeofenceManager(dataManager); - calendarManager = new CalendarManager(dataManager); - notificationManager = new NotificationManager(dataManager); + notificationManager = new NotificationManager(dataManager, Main.getInjector().getInstance(CacheManager.class)); notificatorManager = new NotificatorManager(); Properties velocityProperties = new Properties(); velocityProperties.setProperty("file.resource.loader.path", @@ -330,8 +322,6 @@ public final class Context { return (BaseObjectManager) groupsManager; } else if (clazz.equals(User.class)) { return (BaseObjectManager) usersManager; - } else if (clazz.equals(Calendar.class)) { - return (BaseObjectManager) calendarManager; } else if (clazz.equals(Geofence.class)) { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index fb70a51c6..b757b99a7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -23,7 +23,6 @@ import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.CalendarManager; import org.traccar.database.LdapProvider; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; @@ -125,11 +124,6 @@ public class MainModule extends AbstractModule { return Context.getGeofenceManager(); } - @Provides - public static CalendarManager provideCalendarManager() { - return Context.getCalendarManager(); - } - @Provides public static SmsManager provideSmsManager() { return Context.getSmsManager(); diff --git a/src/main/java/org/traccar/database/CalendarManager.java b/src/main/java/org/traccar/database/CalendarManager.java deleted file mode 100644 index 44ced1082..000000000 --- a/src/main/java/org/traccar/database/CalendarManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 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.database; - -import org.traccar.model.Calendar; - -public class CalendarManager extends SimpleObjectManager { - - public CalendarManager(DataManager dataManager) { - super(dataManager, Calendar.class); - } - -} diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 2f912fff1..fcefb54f0 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -37,16 +37,20 @@ import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); + private final CacheManager cacheManager; + private final boolean geocodeOnRequest; - public NotificationManager(DataManager dataManager) { + public NotificationManager(DataManager dataManager, CacheManager cacheManager) { super(dataManager, Notification.class); + this.cacheManager = cacheManager; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); } @@ -56,7 +60,7 @@ public class NotificationManager extends ExtendedObjectManager { for (long itemId : getUserItems(userId)) { if (getById(itemId).getAlways() || deviceNotifications.contains(itemId)) { long calendarId = getById(itemId).getCalendarId(); - Calendar calendar = calendarId != 0 ? Context.getCalendarManager().getById(calendarId) : null; + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(time)) { result.add(itemId); } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 61b35b380..544faf697 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -19,7 +19,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -361,7 +360,6 @@ public class PermissionsManager { if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); } - Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -387,8 +385,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Calendar.class)) { - Context.getCalendarManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index c7dcf3f59..17e240f68 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.database.CalendarManager; import org.traccar.session.ConnectionManager; import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; @@ -29,24 +28,25 @@ import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { + private final CacheManager cacheManager; private final IdentityManager identityManager; private final GeofenceManager geofenceManager; - private final CalendarManager calendarManager; private final ConnectionManager connectionManager; @Inject public GeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, + CacheManager cacheManager, IdentityManager identityManager, GeofenceManager geofenceManager, ConnectionManager connectionManager) { + this.cacheManager = cacheManager; this.identityManager = identityManager; this.geofenceManager = geofenceManager; - this.calendarManager = calendarManager; this.connectionManager = connectionManager; } @@ -77,7 +77,7 @@ public class GeofenceEventHandler extends BaseEventHandler { Map events = new HashMap<>(); for (long geofenceId : oldGeofences) { long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); - Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position); event.setGeofenceId(geofenceId); @@ -86,7 +86,7 @@ public class GeofenceEventHandler extends BaseEventHandler { } for (long geofenceId : newGeofences) { long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); - Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position); event.setGeofenceId(geofenceId); -- cgit v1.2.3 From 32b39cffc6dd705e9aacbe5b8d68bc37106997d2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 15:44:08 -0700 Subject: Support TopFlyTech UDP protocol --- src/main/java/org/traccar/protocol/T800xProtocol.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index fa692c792..a6f5f1514 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.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. @@ -35,6 +35,13 @@ public class T800xProtocol extends BaseProtocol { pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); } }); + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); + pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); + } + }); } } -- cgit v1.2.3 From b745e3804950fefd24b38937c90c4d5c61219321 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 16:38:58 -0700 Subject: Remove drivers manager --- schema/changelog-5.1.xml | 17 ++++ schema/changelog-master.xml | 1 + src/main/java/org/traccar/Context.java | 12 --- .../java/org/traccar/database/DriversManager.java | 100 --------------------- .../org/traccar/database/PermissionsManager.java | 7 -- .../notification/NotificationFormatter.java | 3 +- .../org/traccar/reports/StopsReportProvider.java | 12 ++- .../org/traccar/reports/TripsReportProvider.java | 12 ++- .../org/traccar/reports/common/ReportUtils.java | 28 +++--- .../org/traccar/session/cache/CacheManager.java | 7 ++ .../java/org/traccar/reports/ReportUtilsTest.java | 43 ++++----- 11 files changed, 85 insertions(+), 157 deletions(-) create mode 100644 schema/changelog-5.1.xml delete mode 100644 src/main/java/org/traccar/database/DriversManager.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml new file mode 100644 index 000000000..26c2088b9 --- /dev/null +++ b/schema/changelog-5.1.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index bb2b3e2f3..471b0fe5d 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -31,5 +31,6 @@ + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index e5a0c640f..899f8ea54 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -26,7 +26,6 @@ import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.DriversManager; import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; @@ -39,7 +38,6 @@ import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Notification; @@ -178,12 +176,6 @@ public final class Context { return eventForwarder; } - private static DriversManager driversManager; - - public static DriversManager getDriversManager() { - return driversManager; - } - private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -277,8 +269,6 @@ public final class Context { eventForwarder = new EventForwarder(config); } - driversManager = new DriversManager(dataManager); - } private static void initEventsModule() { @@ -324,8 +314,6 @@ public final class Context { return (BaseObjectManager) usersManager; } else if (clazz.equals(Geofence.class)) { return (BaseObjectManager) geofenceManager; - } else if (clazz.equals(Driver.class)) { - return (BaseObjectManager) driversManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; } diff --git a/src/main/java/org/traccar/database/DriversManager.java b/src/main/java/org/traccar/database/DriversManager.java deleted file mode 100644 index d111cd643..000000000 --- a/src/main/java/org/traccar/database/DriversManager.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.database; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.traccar.model.Driver; - -public class DriversManager extends ExtendedObjectManager { - - private Map driversByUniqueId; - - public DriversManager(DataManager dataManager) { - super(dataManager, Driver.class); - try { - writeLock(); - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); - } - } finally { - writeUnlock(); - } - } - - private void addByUniqueId(Driver driver) { - try { - writeLock(); - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); - } - driversByUniqueId.put(driver.getUniqueId(), driver); - } finally { - writeUnlock(); - } - } - - private void removeByUniqueId(String driverUniqueId) { - try { - writeLock(); - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); - } - driversByUniqueId.remove(driverUniqueId); - } finally { - writeUnlock(); - } - } - - @Override - protected void addNewItem(Driver driver) { - super.addNewItem(driver); - addByUniqueId(driver); - } - - @Override - protected void updateCachedItem(Driver driver) { - Driver cachedDriver = getById(driver.getId()); - cachedDriver.setName(driver.getName()); - if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { - removeByUniqueId(cachedDriver.getUniqueId()); - cachedDriver.setUniqueId(driver.getUniqueId()); - addByUniqueId(cachedDriver); - } - cachedDriver.setAttributes(driver.getAttributes()); - } - - @Override - protected void removeCachedItem(long driverId) { - Driver cachedDriver = getById(driverId); - if (cachedDriver != null) { - String driverUniqueId = cachedDriver.getUniqueId(); - super.removeCachedItem(driverId); - removeByUniqueId(driverUniqueId); - } - } - - public Driver getDriverByUniqueId(String uniqueId) { - try { - readLock(); - return driversByUniqueId.get(uniqueId); - } finally { - readUnlock(); - } - } -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 544faf697..47941d681 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.ManagedUser; @@ -360,7 +359,6 @@ public class PermissionsManager { if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); } - Context.getDriversManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } @@ -370,7 +368,6 @@ public class PermissionsManager { if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshExtendedPermissions(); } - Context.getDriversManager().refreshExtendedPermissions(); } public void refreshPermissions(Permission permission) { @@ -383,8 +380,6 @@ public class PermissionsManager { usersManager.refreshUserItems(); } else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Driver.class)) { - Context.getDriversManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -392,8 +387,6 @@ public class PermissionsManager { } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Driver.class)) { - Context.getDriversManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index c3e37c9e9..be90761b1 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -17,7 +17,6 @@ package org.traccar.notification; import org.apache.velocity.VelocityContext; -import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -55,7 +54,7 @@ public final class NotificationFormatter { } String driverUniqueId = event.getString(Position.KEY_DRIVER_UNIQUE_ID); if (driverUniqueId != null) { - velocityContext.put("driver", Context.getDriversManager().getDriverByUniqueId(driverUniqueId)); + velocityContext.put("driver", cacheManager.findDriverByUniqueId(device.getId(), driverUniqueId)); } return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 8dedb9a24..58dc71d2d 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -35,10 +35,20 @@ import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class StopsReportProvider { + private final Storage storage; + + @Inject + public StopsReportProvider(Storage storage) { + this.storage = storage; + } + private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -47,7 +57,7 @@ public class StopsReportProvider { DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 6aff08a1d..5ff31dbe2 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -34,10 +34,20 @@ import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class TripsReportProvider { + private final Storage storage; + + @Inject + public TripsReportProvider(Storage storage) { + this.storage = storage; + } + private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -46,7 +56,7 @@ public class TripsReportProvider { DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index b56b58a58..4bcb54899 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -146,9 +146,11 @@ public final class ReportUtils { return null; } - public static String findDriverName(String driverUniqueId) { - if (driverUniqueId != null && Context.getDriversManager() != null) { - Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId); + public static String findDriverName(Storage storage, String driverUniqueId) throws StorageException { + if (driverUniqueId != null) { + Driver driver = storage.getObject(Driver.class, new Request( + new Columns.All(), + new Condition.Equals("uniqueId", "uniqueId", driverUniqueId))); if (driver != null) { return driver.getName(); } @@ -186,8 +188,8 @@ public final class ReportUtils { } private static TripReportItem calculateTrip( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { + Storage storage, IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) throws StorageException { Position startTrip = positions.get(startIndex); Position endTrip = positions.get(endIndex); @@ -238,7 +240,7 @@ public final class ReportUtils { trip.setSpentFuel(calculateFuel(startTrip, endTrip)); trip.setDriverUniqueId(findDriver(startTrip, endTrip)); - trip.setDriverName(findDriverName(trip.getDriverUniqueId())); + trip.setDriverName(findDriverName(storage, trip.getDriverUniqueId())); if (!ignoreOdometer && startTrip.getDouble(Position.KEY_ODOMETER) != 0 @@ -303,11 +305,11 @@ public final class ReportUtils { } private static T calculateTripOrStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { + Storage storage, IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(storage, identityManager, positions, startIndex, endIndex, ignoreOdometer); } else { return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); } @@ -334,9 +336,9 @@ public final class ReportUtils { } public static Collection detectTripsAndStops( - IdentityManager identityManager, DeviceManager deviceManager, + Storage storage, IdentityManager identityManager, DeviceManager deviceManager, Collection positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { + TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) throws StorageException { Collection result = new ArrayList<>(); @@ -369,13 +371,13 @@ public final class ReportUtils { } if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(identityManager, positions, + result.add(calculateTripOrStop(storage, identityManager, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(identityManager, positions, + result.add(calculateTripOrStop(storage, identityManager, positions, startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, ignoreOdometer, reportClass)); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 102a31ecd..6ea0f252d 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -105,6 +105,13 @@ public class CacheManager { } } + public Driver findDriverByUniqueId(long deviceId, String driverUniqueId) { + return getDeviceObjects(deviceId, Driver.class).stream() + .filter(driver -> driver.getUniqueId().equals(driverUniqueId)) + .findFirst() + .orElse(null); + } + public void addDevice(long deviceId) throws StorageException { try { lock.writeLock().lock(); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index e947a9afa..9b287a0fd 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -9,6 +9,7 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; import org.traccar.reports.common.TripsConfig; +import org.traccar.storage.Storage; import java.text.DateFormat; import java.text.ParseException; @@ -79,7 +80,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripsSimple() throws ParseException { + public void testDetectTripsSimple() throws Exception { List data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -94,7 +95,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -109,7 +110,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -131,7 +132,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripsSimpleWithIgnition() throws ParseException { + public void testDetectTripsSimpleWithIgnition() throws Exception { List data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -148,7 +149,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -163,7 +164,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -178,7 +179,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -200,7 +201,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripsWithFluctuation() throws ParseException { + public void testDetectTripsWithFluctuation() throws Exception { List data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -219,7 +220,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -234,7 +235,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -256,7 +257,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsOnly() throws ParseException { + public void testDetectStopsOnly() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -269,7 +270,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -283,7 +284,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsWithTripCut() throws ParseException { + public void testDetectStopsWithTripCut() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -296,7 +297,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -310,7 +311,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsStartedFromTrip() throws ParseException { + public void testDetectStopsStartedFromTrip() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 2, 0), @@ -323,7 +324,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -337,7 +338,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsMoving() throws ParseException { + public void testDetectStopsMoving() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 5, 0), @@ -350,7 +351,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -358,7 +359,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripAndStopByGap() throws ParseException { + public void testDetectTripAndStopByGap() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 7, 100), @@ -373,7 +374,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -388,7 +389,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(600, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 104281f161f622df8fca0c65a5b9969ceb03c46f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 18:04:24 -0700 Subject: Extract user utils from reports --- build.gradle | 2 +- src/main/java/org/traccar/Main.java | 3 +- .../org/traccar/api/resource/PasswordResource.java | 3 +- .../traccar/api/security/PermissionsService.java | 2 + .../org/traccar/database/PermissionsManager.java | 12 ----- src/main/java/org/traccar/helper/UserUtil.java | 57 ++++++++++++++++++++++ .../notification/NotificationFormatter.java | 12 +++-- .../notification/TextTemplateFormatter.java | 9 ++-- .../org/traccar/reports/EventsReportProvider.java | 8 ++- .../org/traccar/reports/RouteReportProvider.java | 13 ++++- .../org/traccar/reports/StopsReportProvider.java | 8 ++- .../org/traccar/reports/SummaryReportProvider.java | 19 ++++++-- .../org/traccar/reports/TripsReportProvider.java | 8 ++- .../org/traccar/reports/common/ReportUtils.java | 30 +++--------- .../org/traccar/session/cache/CacheManager.java | 36 +++++++++++--- src/main/java/org/traccar/web/WebServer.java | 3 ++ 16 files changed, 162 insertions(+), 63 deletions(-) create mode 100644 src/main/java/org/traccar/helper/UserUtil.java (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index de8c86712..8c196043a 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ dependencies { implementation "io.netty:netty-all:4.1.66.Final" implementation "org.slf4j:slf4j-jdk14:2.0.0-alpha6" implementation "com.google.inject:guice:$guiceVersion" - implementation "com.google.inject.extensions:guice-assistedinject:$guiceVersion" + implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" implementation "org.glassfish:javax.json:1.1.4" implementation "org.eclipse.jetty:jetty-server:$jettyVersion" diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index db9892bb9..b14f22a00 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -17,6 +17,7 @@ package org.traccar; import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.servlet.ServletModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.schedule.ScheduleManager; @@ -111,7 +112,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule()); + injector = Guice.createInjector(new MainModule(), new ServletModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index ed7131718..91d994153 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -51,7 +51,8 @@ public class PasswordResource extends BaseResource { String token = UUID.randomUUID().toString().replaceAll("-", ""); user.set(PASSWORD_RESET_TOKEN, token); Context.getUsersManager().updateItem(user); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(null); + VelocityContext velocityContext = TextTemplateFormatter.prepareContext( + permissionsService.getServer(), user); velocityContext.put("token", token); NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 9ec3b43c1..c70414b2a 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import com.google.inject.servlet.RequestScoped; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; @@ -34,6 +35,7 @@ import org.traccar.storage.query.Request; import javax.inject.Inject; +@RequestScoped public class PermissionsService { private final Storage storage; diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 47941d681..e8f2380a2 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -412,16 +412,4 @@ public class PermissionsManager { return null; } - public Object lookupAttribute(long userId, String key, Object defaultValue) { - Object preference; - Object serverPreference = server.getAttributes().get(key); - Object userPreference = getUser(userId).getAttributes().get(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - } diff --git a/src/main/java/org/traccar/helper/UserUtil.java b/src/main/java/org/traccar/helper/UserUtil.java new file mode 100644 index 000000000..6050ad349 --- /dev/null +++ b/src/main/java/org/traccar/helper/UserUtil.java @@ -0,0 +1,57 @@ +/* + * 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.helper; + +import org.traccar.model.Server; +import org.traccar.model.User; + +import java.util.TimeZone; + +public final class UserUtil { + + private UserUtil() { + } + + public static String getDistanceUnit(Server server, User user) { + return lookupStringAttribute(server, user, "distanceUnit", "km"); + } + + public static String getSpeedUnit(Server server, User user) { + return lookupStringAttribute(server, user, "speedUnit", "kn"); + } + + public static String getVolumeUnit(Server server, User user) { + return lookupStringAttribute(server, user, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(Server server, User user) { + String timezone = lookupStringAttribute(server, user, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { + String preference; + String serverPreference = server.getString(key); + String userPreference = user.getString(key); + if (server.getForceSettings()) { + preference = serverPreference != null ? serverPreference : userPreference; + } else { + preference = userPreference != null ? userPreference : serverPreference; + } + return preference != null ? preference : defaultValue; + } + +} diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index be90761b1..13f42a8b2 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -17,13 +17,14 @@ package org.traccar.notification; import org.apache.velocity.VelocityContext; +import org.traccar.helper.UserUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.reports.common.ReportUtils; import org.traccar.session.cache.CacheManager; public final class NotificationFormatter { @@ -34,17 +35,18 @@ public final class NotificationFormatter { public static NotificationMessage formatMessage( CacheManager cacheManager, User user, Event event, Position position, String templatePath) { + Server server = cacheManager.getServer(); Device device = cacheManager.getObject(Device.class, event.getDeviceId()); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(user); + VelocityContext velocityContext = TextTemplateFormatter.prepareContext(server, user); velocityContext.put("device", device); velocityContext.put("event", event); if (position != null) { velocityContext.put("position", position); - velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(user.getId())); - velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(user.getId())); - velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(user.getId())); + velocityContext.put("speedUnit", UserUtil.getSpeedUnit(server, user)); + velocityContext.put("distanceUnit", UserUtil.getDistanceUnit(server, user)); + velocityContext.put("volumeUnit", UserUtil.getVolumeUnit(server, user)); } if (event.getGeofenceId() != 0) { velocityContext.put("geofence", cacheManager.getObject(Geofence.class, event.getGeofenceId())); diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 469de2d4a..06375afac 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.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,8 +23,9 @@ import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.helper.UserUtil; +import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.reports.common.ReportUtils; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -38,13 +39,13 @@ public final class TextTemplateFormatter { private TextTemplateFormatter() { } - public static VelocityContext prepareContext(User user) { + public static VelocityContext prepareContext(Server server, User user) { VelocityContext velocityContext = new VelocityContext(); if (user != null) { velocityContext.put("user", user); - velocityContext.put("timezone", ReportUtils.getTimezone(user.getId())); + velocityContext.put("timezone", UserUtil.getTimezone(server, user)); } velocityContext.put("webUrl", Context.getVelocityEngine().getProperty("web.url")); diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 9b4a7df2b..f0c8c31b6 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -28,6 +28,7 @@ import java.util.Iterator; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -42,10 +43,12 @@ import javax.inject.Inject; public class EventsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public EventsReportProvider(Storage storage) { + public EventsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -127,7 +130,8 @@ public class EventsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesEvents); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("geofenceNames", geofenceNames); diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 4c4a41405..e20ba6885 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -26,6 +26,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; @@ -33,8 +34,17 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class RouteReportProvider { + private final PermissionsService permissionsService; + + @Inject + public RouteReportProvider(PermissionsService permissionsService) { + this.permissionsService = permissionsService; + } + public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); @@ -72,7 +82,8 @@ public class RouteReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesRoutes); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 58dc71d2d..8899dc42f 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -28,6 +28,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; +import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; @@ -42,10 +43,12 @@ import javax.inject.Inject; public class StopsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public StopsReportProvider(Storage storage) { + public StopsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -98,7 +101,8 @@ public class StopsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesStops); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index a2306f3d1..c9fac4309 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -27,14 +27,25 @@ import java.util.Date; import org.jxls.util.JxlsHelper; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class SummaryReportProvider { + private final PermissionsService permissionsService; + + @Inject + public SummaryReportProvider(PermissionsService permissionsService) { + this.permissionsService = permissionsService; + } + private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(deviceId); @@ -88,8 +99,9 @@ public class SummaryReportProvider { return result; } - private int getDay(long userId, Date date) { - Calendar calendar = Calendar.getInstance(ReportUtils.getTimezone(userId)); + private int getDay(long userId, Date date) throws StorageException { + Calendar calendar = Calendar.getInstance(UserUtil.getTimezone( + permissionsService.getServer(), permissionsService.getUser(userId))); calendar.setTime(date); return calendar.get(Calendar.DAY_OF_MONTH); } @@ -144,7 +156,8 @@ public class SummaryReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("summaries", summaries); jxlsContext.putVar("from", from); jxlsContext.putVar("to", to); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 5ff31dbe2..bcd79ab25 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -27,6 +27,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; +import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; @@ -41,10 +42,12 @@ import javax.inject.Inject; public class TripsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public TripsReportProvider(Storage storage) { + public TripsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -96,7 +99,8 @@ public class TripsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesTrips); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 4bcb54899..71c49f65b 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,7 +31,9 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.UserUtil; import org.traccar.model.BaseModel; +import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.DeviceState; import org.traccar.model.Driver; @@ -58,7 +60,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.TimeZone; public final class ReportUtils { @@ -81,23 +82,6 @@ public final class ReportUtils { } } - public static String getDistanceUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); - } - - public static String getSpeedUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); - } - - public static String getVolumeUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(long userId) { - String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { @@ -158,15 +142,15 @@ public final class ReportUtils { return null; } - public static org.jxls.common.Context initializeContext(long userId) { + public static org.jxls.common.Context initializeContext(Server server, User user) { org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); - jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); - jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); + jxlsContext.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); + jxlsContext.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); + jxlsContext.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); jxlsContext.putVar("dateTool", new DateTool()); jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", getTimezone(userId)); + jxlsContext.putVar("timezone", UserUtil.getTimezone(server, user)); jxlsContext.putVar("locale", Locale.getDefault()); jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); return jxlsContext; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 6ea0f252d..586237655 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -23,6 +23,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; +import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -57,12 +58,14 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); + private Server server; private final Map devicePositions = new HashMap<>(); private final Map> notificationUsers = new HashMap<>(); @Inject public CacheManager(Storage storage) throws StorageException { this.storage = storage; + invalidateServer(); invalidateUsers(); } @@ -96,6 +99,15 @@ public class CacheManager { } } + public Server getServer() { + try { + lock.readLock().lock(); + return server; + } finally { + lock.readLock().unlock(); + } + } + public List getNotificationUsers(long notificationId) { try { lock.readLock().lock(); @@ -154,6 +166,10 @@ public class CacheManager { invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); } + private void invalidateServer() throws StorageException { + server = storage.getObject(Server.class, new Request(new Columns.All())); + } + private void invalidateUsers() throws StorageException { Map users = new HashMap<>(); storage.getObjects(User.class, new Request(new Columns.All())) @@ -220,21 +236,29 @@ public class CacheManager { } private void unsafeInvalidate(CacheKey[] keys) throws StorageException { + boolean invalidateServer = false; boolean invalidateUsers = false; Set linkedDevices = new HashSet<>(); for (var key : keys) { - if (key.classIs(User.class) || key.classIs(Notification.class)) { - invalidateUsers = true; + if (key.classIs(Server.class)) { + invalidateServer = true; + } else { + if (key.classIs(User.class) || key.classIs(Notification.class)) { + invalidateUsers = true; + } + deviceCache.computeIfPresent(key, (k, value) -> { + linkedDevices.addAll(value.getReferences()); + return value; + }); } - deviceCache.computeIfPresent(key, (k, value) -> { - linkedDevices.addAll(value.getReferences()); - return value; - }); } for (long deviceId : linkedDevices) { unsafeRemoveDevice(deviceId); unsafeAddDevice(deviceId); } + if (invalidateServer) { + invalidateServer(); + } if (invalidateUsers) { invalidateUsers(); } diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 06676fb41..f1ee8fcb2 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,6 +15,7 @@ */ package org.traccar.web; +import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; @@ -164,6 +165,8 @@ public class WebServer implements LifecycleObject { } private void initApi(Config config, ServletContextHandler servletHandler) { + servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); + servletHandler.addServlet(new ServletHolder(new AsyncSocketServlet()), "/api/socket"); JettyWebSocketServletContainerInitializer.configure(servletHandler, null); -- cgit v1.2.3 From 5890e03199142f041dc19160329a740b4d01450d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 19:23:16 -0700 Subject: Fix last position requests (fix #4863) --- .../java/org/traccar/api/resource/AttributeResource.java | 16 +++------------- src/main/java/org/traccar/database/CommandsManager.java | 2 +- 2 files changed, 4 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index fdd0d4f6f..ab7e43add 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -53,22 +53,12 @@ public class AttributeResource extends ExtendedObjectResource { permissionsService.checkAdmin(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), deviceId); - Device device = storage.getObject(Device.class, new Request( + Position position = storage.getObject(Position.class, new Request( new Columns.All(), - new Condition.Equals("id", "id", deviceId))); - if (device == null) { - throw new IllegalArgumentException("Device not found"); - } - - Position last = storage.getObject(Position.class, new Request( - new Columns.All(), - new Condition.Equals("id", "id", device.getPositionId()))); - if (last == null) { - throw new IllegalArgumentException("Device has no last position"); - } + new Condition.LatestPositions(deviceId))); Object result = new ComputedAttributesHandler(Context.getConfig(), Context.getIdentityManager(), null) - .computeAttribute(entity, last); + .computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { case "number": diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 8dd2ba8b7..2967b8abd 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -72,7 +72,7 @@ public class CommandsManager { long deviceId = command.getDeviceId(); if (command.getTextChannel()) { Device device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.Include("positionId", "phone"), new Condition.Equals("id", "id", deviceId))); Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", device.getPositionId()))); if (position != null) { -- cgit v1.2.3 From cd229daa23cfc43ad5056c45c4aaecefdbbf826c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 8 Jun 2022 07:52:59 -0700 Subject: Improve cache invalidation --- .../java/org/traccar/api/BaseObjectResource.java | 8 ++++ .../traccar/api/resource/PermissionsResource.java | 9 ++++ .../handler/events/MaintenanceEventHandler.java | 3 +- .../org/traccar/session/cache/CacheManager.java | 50 ++++++++++++---------- .../java/org/traccar/session/cache/CacheValue.java | 6 ++- 5 files changed, 52 insertions(+), 24 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index d6401dc42..c033fbb62 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -27,11 +27,13 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -42,6 +44,9 @@ import javax.ws.rs.core.Response; public abstract class BaseObjectResource extends BaseResource { + @Inject + private CacheManager cacheManager; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -75,6 +80,7 @@ public abstract class BaseObjectResource extends BaseResour LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); + cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); if (manager instanceof SimpleObjectManager) { @@ -100,6 +106,7 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); } + cacheManager.updateOrInvalidate(baseClass, entity.getId()); LogAction.edit(getUserId(), entity); @@ -128,6 +135,7 @@ public abstract class BaseObjectResource extends BaseResour } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } + cacheManager.updateOrInvalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 484c61e66..a4db6754c 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -20,8 +20,10 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Permission; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.POST; @@ -40,6 +42,9 @@ import java.util.Set; @Consumes(MediaType.APPLICATION_JSON) public class PermissionsResource extends BaseResource { + @Inject + private CacheManager cacheManager; + private void checkPermission(Permission permission, boolean link) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -67,6 +72,8 @@ public class PermissionsResource extends BaseResource { checkPermission(permission, true); Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId(), true); + cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } @@ -91,6 +98,8 @@ public class PermissionsResource extends BaseResource { checkPermission(permission, false); Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId(), false); + cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index be3e9bf8d..f85aab043 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.Map; import io.netty.channel.ChannelHandler; +import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; @@ -39,7 +40,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { @Override protected Map analyzePosition(Position position) { - Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) < 0) { return null; } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 586237655..8e1737441 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -20,9 +20,9 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; +import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; -import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; @@ -59,7 +59,6 @@ public class CacheManager { private final Map, List>> deviceLinks = new HashMap<>(); private Server server; - private final Map devicePositions = new HashMap<>(); private final Map> notificationUsers = new HashMap<>(); @Inject @@ -90,15 +89,6 @@ public class CacheManager { } } - public Position getPosition(long deviceId) { - try { - lock.readLock().lock(); - return devicePositions.get(deviceId); - } finally { - lock.readLock().unlock(); - } - } - public Server getServer() { try { lock.readLock().lock(); @@ -146,18 +136,34 @@ public class CacheManager { } } - public void updatePosition(Position position) { - try { - lock.writeLock().lock(); - devicePositions.put(position.getDeviceId(), position); - } finally { - lock.writeLock().unlock(); + public void updateOrInvalidate(Class clazz, long id) throws StorageException { + boolean invalidate = false; + var before = getObject(clazz, id); + var after = storage.getObject(clazz, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); + if (before == null) { + return; + } else if (after == null) { + invalidate = true; + } else if (clazz.isInstance(GroupedModel.class)) { + if (((GroupedModel) before).getGroupId() != ((GroupedModel) after).getGroupId()) { + invalidate = true; + } + } + if (invalidate) { + invalidate(new CacheKey(clazz, id)); + } else { + try { + lock.writeLock().lock(); + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + if (cacheValue != null) { + cacheValue.setValue(after); + } + // TODO if device, also need to update geofences + } finally { + lock.writeLock().unlock(); + } } - } - - public void invalidate( - Class clazz, long id) throws StorageException { - invalidate(new CacheKey(clazz, id)); } public void invalidate( diff --git a/src/main/java/org/traccar/session/cache/CacheValue.java b/src/main/java/org/traccar/session/cache/CacheValue.java index 9e955dfe5..1f0383ce5 100644 --- a/src/main/java/org/traccar/session/cache/CacheValue.java +++ b/src/main/java/org/traccar/session/cache/CacheValue.java @@ -22,7 +22,7 @@ import java.util.Set; class CacheValue { - private final BaseModel value; + private BaseModel value; private final Set references = new HashSet<>(); CacheValue(BaseModel value) { @@ -42,6 +42,10 @@ class CacheValue { return (T) value; } + public void setValue(BaseModel value) { + this.value = value; + } + public Set getReferences() { return references; } -- cgit v1.2.3 From 65d3654dcca878cfd839e40c0dd020da199be09e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 8 Jun 2022 08:14:20 -0700 Subject: More cache improvements --- .../java/org/traccar/api/BaseObjectResource.java | 4 +-- .../org/traccar/session/cache/CacheManager.java | 35 +++++++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index c033fbb62..eb1db5e89 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -106,7 +106,7 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); } - cacheManager.updateOrInvalidate(baseClass, entity.getId()); + cacheManager.updateOrInvalidate(entity); LogAction.edit(getUserId(), entity); @@ -135,7 +135,7 @@ public abstract class BaseObjectResource extends BaseResour } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } - cacheManager.updateOrInvalidate(baseClass, id); + cacheManager.invalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 8e1737441..a934431be 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -136,36 +136,43 @@ public class CacheManager { } } - public void updateOrInvalidate(Class clazz, long id) throws StorageException { - boolean invalidate = false; - var before = getObject(clazz, id); - var after = storage.getObject(clazz, new Request( + public void updateOrInvalidate(Class clazz, long id) throws StorageException { + var object = storage.getObject(clazz, new Request( new Columns.All(), new Condition.Equals("id", "id", id))); + if (object != null) { + updateOrInvalidate(object); + } else { + invalidate(clazz, id); + } + } + + public void updateOrInvalidate(T object) throws StorageException { + boolean invalidate = false; + var before = getObject(object.getClass(), object.getId()); if (before == null) { return; - } else if (after == null) { - invalidate = true; - } else if (clazz.isInstance(GroupedModel.class)) { - if (((GroupedModel) before).getGroupId() != ((GroupedModel) after).getGroupId()) { + } else if (object instanceof GroupedModel) { + if (((GroupedModel) before).getGroupId() != ((GroupedModel) object).getGroupId()) { invalidate = true; } } if (invalidate) { - invalidate(new CacheKey(clazz, id)); + invalidate(object.getClass(), object.getId()); } else { + // TODO if device, also need to update geofences try { lock.writeLock().lock(); - var cacheValue = deviceCache.get(new CacheKey(clazz, id)); - if (cacheValue != null) { - cacheValue.setValue(after); - } - // TODO if device, also need to update geofences + deviceCache.get(new CacheKey(object.getClass(), object.getId())).setValue(object); } finally { lock.writeLock().unlock(); } } } + public void invalidate(Class clazz, long id) throws StorageException { + invalidate(new CacheKey(clazz, id)); + } + public void invalidate( Class clazz1, long id1, Class clazz2, long id2) throws StorageException { -- cgit v1.2.3 From c4ff983ffe9a03a57d3ab0596abe8bce08c1ae2e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 06:39:10 -0700 Subject: Add position cache --- src/main/java/org/traccar/MainEventHandler.java | 2 ++ .../java/org/traccar/database/DeviceManager.java | 3 ++ .../org/traccar/session/cache/CacheManager.java | 33 ++++++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index f04307fdb..bb84a09d2 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -28,6 +28,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -60,6 +61,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { Position position = (Position) msg; try { Context.getDeviceManager().updateLatestPosition(position); + Main.getInjector().getInstance(CacheManager.class).updatePosition(position); } catch (StorageException error) { LOGGER.warn("Failed to update device", error); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index b1ea0b8b7..0bac8f642 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicLong; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.Main; import org.traccar.config.Config; import org.traccar.Context; import org.traccar.config.Keys; @@ -36,6 +37,7 @@ import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; public class DeviceManager extends BaseObjectManager implements IdentityManager { @@ -406,6 +408,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } getDataManager().addObject(last); updateLatestPosition(last); + Main.getInjector().getInstance(CacheManager.class).updatePosition(last); } else { throw new IllegalArgumentException(); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index a934431be..4b42ea4e5 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -23,6 +23,7 @@ import org.traccar.model.Geofence; import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; +import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; @@ -57,6 +58,7 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); + private final Map devicePositions = new HashMap<>(); private Server server; private final Map> notificationUsers = new HashMap<>(); @@ -89,6 +91,15 @@ public class CacheManager { } } + public Position getPosition(long deviceId) { + try { + lock.readLock().lock(); + return devicePositions.get(deviceId); + } finally { + lock.readLock().unlock(); + } + } + public Server getServer() { try { lock.readLock().lock(); @@ -136,6 +147,17 @@ public class CacheManager { } } + public void updatePosition(Position position) { + try { + lock.writeLock().lock(); + if (deviceLinks.containsKey(position.getDeviceId())) { + devicePositions.put(position.getDeviceId(), position); + } + } finally { + lock.writeLock().unlock(); + } + } + public void updateOrInvalidate(Class clazz, long id) throws StorageException { var object = storage.getObject(clazz, new Request( new Columns.All(), new Condition.Equals("id", "id", id))); @@ -201,8 +223,9 @@ public class CacheManager { private void unsafeAddDevice(long deviceId) throws StorageException { Map, List> links = new HashMap<>(); - addObject(deviceId, storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId)))); + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + addObject(deviceId, device); for (Class clazz : CLASSES) { var objects = storage.getObjects(clazz, new Request( @@ -226,6 +249,11 @@ public class CacheManager { } deviceLinks.put(deviceId, links); + + if (device.getPositionId() > 0) { + devicePositions.put(deviceId, storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + } } private void unsafeRemoveDevice(long deviceId) { @@ -237,6 +265,7 @@ public class CacheManager { return value.getReferences().size() > 0 ? value : null; }); })); + devicePositions.remove(deviceId); } private void invalidate(CacheKey... keys) throws StorageException { -- cgit v1.2.3 From 12fe28bebbdbc61214363a9c7b51bd300ed62c15 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 07:00:20 -0700 Subject: Remove geofence manager --- src/main/java/org/traccar/Context.java | 11 ---- src/main/java/org/traccar/MainModule.java | 6 -- .../java/org/traccar/api/BaseObjectResource.java | 1 - .../java/org/traccar/database/DeviceManager.java | 6 -- .../java/org/traccar/database/GeofenceManager.java | 66 ---------------------- .../org/traccar/database/PermissionsManager.java | 13 +---- .../handler/events/GeofenceEventHandler.java | 34 +++++------ .../handler/events/OverspeedEventHandler.java | 12 ++-- src/main/java/org/traccar/helper/UserUtil.java | 57 ------------------- .../org/traccar/helper/model/GeofenceUtil.java | 40 +++++++++++++ .../org/traccar/helper/model/PositionUtil.java | 31 ++++++++++ .../java/org/traccar/helper/model/UserUtil.java | 57 +++++++++++++++++++ .../notification/NotificationFormatter.java | 2 +- .../notification/TextTemplateFormatter.java | 2 +- .../org/traccar/reports/SummaryReportProvider.java | 2 +- .../org/traccar/reports/common/ReportUtils.java | 2 +- .../org/traccar/session/cache/CacheManager.java | 15 ++++- 17 files changed, 167 insertions(+), 190 deletions(-) delete mode 100644 src/main/java/org/traccar/database/GeofenceManager.java delete mode 100644 src/main/java/org/traccar/helper/UserUtil.java create mode 100644 src/main/java/org/traccar/helper/model/GeofenceUtil.java create mode 100644 src/main/java/org/traccar/helper/model/PositionUtil.java create mode 100644 src/main/java/org/traccar/helper/model/UserUtil.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 899f8ea54..dcbe6c811 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -26,7 +26,6 @@ import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.MailManager; @@ -38,7 +37,6 @@ import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Notification; import org.traccar.model.User; @@ -140,12 +138,6 @@ public final class Context { return broadcastService; } - private static GeofenceManager geofenceManager; - - public static GeofenceManager getGeofenceManager() { - return geofenceManager; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -273,7 +265,6 @@ public final class Context { private static void initEventsModule() { - geofenceManager = new GeofenceManager(dataManager); notificationManager = new NotificationManager(dataManager, Main.getInjector().getInstance(CacheManager.class)); notificatorManager = new NotificatorManager(); Properties velocityProperties = new Properties(); @@ -312,8 +303,6 @@ public final class Context { return (BaseObjectManager) groupsManager; } else if (clazz.equals(User.class)) { return (BaseObjectManager) usersManager; - } else if (clazz.equals(Geofence.class)) { - return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b757b99a7..bb264cff3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -27,7 +27,6 @@ import org.traccar.database.LdapProvider; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; @@ -119,11 +118,6 @@ public class MainModule extends AbstractModule { return Context.getDeviceManager(); } - @Provides - public static GeofenceManager provideGeofenceManager() { - return Context.getGeofenceManager(); - } - @Provides public static SmsManager provideSmsManager() { return Context.getSmsManager(); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index eb1db5e89..cc930c591 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -151,7 +151,6 @@ public abstract class BaseObjectResource extends BaseResour Context.getPermissionsManager().refreshAllExtendedPermissions(); } } else if (baseClass.equals(Calendar.class)) { - Context.getGeofenceManager().refreshItems(); Context.getNotificationManager().refreshItems(); } return Response.noContent().build(); diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 0bac8f642..20f179f2e 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -218,12 +218,6 @@ public class DeviceManager extends BaseObjectManager implements Identity protected void addNewItem(Device device) { super.addNewItem(device); addByUniqueId(device); - if (Context.getGeofenceManager() != null) { - Position lastPosition = getLastPosition(device.getId()); - if (lastPosition != null) { - device.setGeofenceIds(Context.getGeofenceManager().getCurrentDeviceGeofences(lastPosition)); - } - } } @Override diff --git a/src/main/java/org/traccar/database/GeofenceManager.java b/src/main/java/org/traccar/database/GeofenceManager.java deleted file mode 100644 index a32847cf9..000000000 --- a/src/main/java/org/traccar/database/GeofenceManager.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 - 2017 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.database; - -import java.util.ArrayList; -import java.util.List; - -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Geofence; -import org.traccar.model.Position; - -public class GeofenceManager extends ExtendedObjectManager { - - public GeofenceManager(DataManager dataManager) { - super(dataManager, Geofence.class); - } - - @Override - public final void refreshExtendedPermissions() { - super.refreshExtendedPermissions(); - recalculateDevicesGeofences(); - } - - public List getCurrentDeviceGeofences(Position position) { - List result = new ArrayList<>(); - for (long geofenceId : getAllDeviceItems(position.getDeviceId())) { - Geofence geofence = getById(geofenceId); - if (geofence != null && geofence.getGeometry() - .containsPoint(position.getLatitude(), position.getLongitude())) { - result.add(geofenceId); - } - } - return result; - } - - public void recalculateDevicesGeofences() { - for (Device device : Context.getDeviceManager().getAllDevices()) { - List deviceGeofenceIds = device.getGeofenceIds(); - if (deviceGeofenceIds == null) { - deviceGeofenceIds = new ArrayList<>(); - } else { - deviceGeofenceIds.clear(); - } - Position lastPosition = Context.getIdentityManager().getLastPosition(device.getId()); - if (lastPosition != null && getAllDeviceItems(device.getId()) != null) { - deviceGeofenceIds.addAll(getCurrentDeviceGeofences(lastPosition)); - } - device.setGeofenceIds(deviceGeofenceIds); - } - } - -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index e8f2380a2..3c74c0049 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; @@ -356,18 +355,12 @@ public class PermissionsManager { } public void refreshAllUsersPermissions() { - if (Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshUserItems(); - } if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } } public void refreshAllExtendedPermissions() { - if (Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshExtendedPermissions(); - } } public void refreshPermissions(Permission permission) { @@ -378,16 +371,12 @@ public class PermissionsManager { refreshAllExtendedPermissions(); } else if (permission.getPropertyClass().equals(ManagedUser.class)) { usersManager.refreshUserItems(); - } else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { - if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Notification.class) + if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); } diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 17e240f68..724f8f0d0 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -15,52 +15,46 @@ */ package org.traccar.handler.events; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import io.netty.channel.ChannelHandler; -import org.traccar.session.ConnectionManager; -import org.traccar.database.GeofenceManager; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.GeofenceUtil; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Event; +import org.traccar.model.Geofence; import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { private final CacheManager cacheManager; - private final IdentityManager identityManager; - private final GeofenceManager geofenceManager; private final ConnectionManager connectionManager; @Inject - public GeofenceEventHandler( - CacheManager cacheManager, IdentityManager identityManager, GeofenceManager geofenceManager, - ConnectionManager connectionManager) { + public GeofenceEventHandler(CacheManager cacheManager, ConnectionManager connectionManager) { this.cacheManager = cacheManager; - this.identityManager = identityManager; - this.geofenceManager = geofenceManager; this.connectionManager = connectionManager; } @Override protected Map analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device == null) { return null; } - if (!identityManager.isLatestPosition(position) || !position.getValid()) { + if (!PositionUtil.isLatest(cacheManager, position) || !position.getValid()) { return null; } - List currentGeofences = geofenceManager.getCurrentDeviceGeofences(position); + List currentGeofences = GeofenceUtil.getCurrentGeofences(cacheManager, position); List oldGeofences = new ArrayList<>(); if (device.getGeofenceIds() != null) { oldGeofences.addAll(device.getGeofenceIds()); @@ -76,7 +70,7 @@ public class GeofenceEventHandler extends BaseEventHandler { Map events = new HashMap<>(); for (long geofenceId : oldGeofences) { - long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + long calendarId = cacheManager.getObject(Geofence.class, geofenceId).getCalendarId(); Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position); @@ -85,7 +79,7 @@ public class GeofenceEventHandler extends BaseEventHandler { } } for (long geofenceId : newGeofences) { - long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + long calendarId = cacheManager.getObject(Geofence.class, geofenceId).getCalendarId(); Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position); diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 84d80e55f..45bb13be5 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -23,12 +23,12 @@ import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; import org.traccar.model.Device; import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -39,16 +39,16 @@ public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private final DeviceManager deviceManager; - private final GeofenceManager geofenceManager; + private final CacheManager cacheManager; private final boolean notRepeat; private final long minimalDuration; private final boolean preferLowest; @Inject - public OverspeedEventHandler(Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { + public OverspeedEventHandler(Config config, DeviceManager deviceManager, CacheManager cacheManager) { this.deviceManager = deviceManager; - this.geofenceManager = geofenceManager; + this.cacheManager = cacheManager; notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT); minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); @@ -133,9 +133,9 @@ public class OverspeedEventHandler extends BaseEventHandler { double geofenceSpeedLimit = 0; long overspeedGeofenceId = 0; - if (geofenceManager != null && device.getGeofenceIds() != null) { + if (device.getGeofenceIds() != null) { for (long geofenceId : device.getGeofenceIds()) { - Geofence geofence = geofenceManager.getById(geofenceId); + Geofence geofence = cacheManager.getObject(Geofence.class, geofenceId); if (geofence != null) { double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT); if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0 diff --git a/src/main/java/org/traccar/helper/UserUtil.java b/src/main/java/org/traccar/helper/UserUtil.java deleted file mode 100644 index 6050ad349..000000000 --- a/src/main/java/org/traccar/helper/UserUtil.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.helper; - -import org.traccar.model.Server; -import org.traccar.model.User; - -import java.util.TimeZone; - -public final class UserUtil { - - private UserUtil() { - } - - public static String getDistanceUnit(Server server, User user) { - return lookupStringAttribute(server, user, "distanceUnit", "km"); - } - - public static String getSpeedUnit(Server server, User user) { - return lookupStringAttribute(server, user, "speedUnit", "kn"); - } - - public static String getVolumeUnit(Server server, User user) { - return lookupStringAttribute(server, user, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(Server server, User user) { - String timezone = lookupStringAttribute(server, user, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - - private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { - String preference; - String serverPreference = server.getString(key); - String userPreference = user.getString(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - -} diff --git a/src/main/java/org/traccar/helper/model/GeofenceUtil.java b/src/main/java/org/traccar/helper/model/GeofenceUtil.java new file mode 100644 index 000000000..f56bf4224 --- /dev/null +++ b/src/main/java/org/traccar/helper/model/GeofenceUtil.java @@ -0,0 +1,40 @@ +/* + * 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.helper.model; + +import org.traccar.model.Geofence; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import java.util.ArrayList; +import java.util.List; + +public final class GeofenceUtil { + + private GeofenceUtil() { + } + + public static List getCurrentGeofences(CacheManager cacheManager, Position position) { + List result = new ArrayList<>(); + for (Geofence geofence : cacheManager.getDeviceObjects(position.getDeviceId(), Geofence.class)) { + if (geofence.getGeometry().containsPoint(position.getLatitude(), position.getLongitude())) { + result.add(geofence.getId()); + } + } + return result; + } + +} diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java new file mode 100644 index 000000000..64216a937 --- /dev/null +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -0,0 +1,31 @@ +/* + * 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.helper.model; + +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +public final class PositionUtil { + + private PositionUtil() { + } + + public static boolean isLatest(CacheManager cacheManager, Position position) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; + } + +} diff --git a/src/main/java/org/traccar/helper/model/UserUtil.java b/src/main/java/org/traccar/helper/model/UserUtil.java new file mode 100644 index 000000000..9919e1d95 --- /dev/null +++ b/src/main/java/org/traccar/helper/model/UserUtil.java @@ -0,0 +1,57 @@ +/* + * 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.helper.model; + +import org.traccar.model.Server; +import org.traccar.model.User; + +import java.util.TimeZone; + +public final class UserUtil { + + private UserUtil() { + } + + public static String getDistanceUnit(Server server, User user) { + return lookupStringAttribute(server, user, "distanceUnit", "km"); + } + + public static String getSpeedUnit(Server server, User user) { + return lookupStringAttribute(server, user, "speedUnit", "kn"); + } + + public static String getVolumeUnit(Server server, User user) { + return lookupStringAttribute(server, user, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(Server server, User user) { + String timezone = lookupStringAttribute(server, user, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { + String preference; + String serverPreference = server.getString(key); + String userPreference = user.getString(key); + if (server.getForceSettings()) { + preference = serverPreference != null ? serverPreference : userPreference; + } else { + preference = userPreference != null ? userPreference : serverPreference; + } + return preference != null ? preference : defaultValue; + } + +} diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 13f42a8b2..2d3b90412 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -17,7 +17,7 @@ package org.traccar.notification; import org.apache.velocity.VelocityContext; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 06375afac..9072ec89e 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -23,7 +23,7 @@ import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.Server; import org.traccar.model.User; diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index c9fac4309..27dc5819d 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -29,7 +29,7 @@ import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.helper.UnitsConverter; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 71c49f65b..36d5c0fb1 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,7 +31,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; import org.traccar.model.Server; import org.traccar.model.User; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 4b42ea4e5..18daeae15 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,7 @@ */ package org.traccar.session.cache; +import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -181,13 +182,16 @@ public class CacheManager { if (invalidate) { invalidate(object.getClass(), object.getId()); } else { - // TODO if device, also need to update geofences try { lock.writeLock().lock(); deviceCache.get(new CacheKey(object.getClass(), object.getId())).setValue(object); } finally { lock.writeLock().unlock(); } + + if (object instanceof Device) { + invalidateDeviceGeofences((Device) object); + } } } @@ -254,6 +258,8 @@ public class CacheManager { devicePositions.put(deviceId, storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); } + + invalidateDeviceGeofences(device); } private void unsafeRemoveDevice(long deviceId) { @@ -306,4 +312,11 @@ public class CacheManager { } } + private void invalidateDeviceGeofences(Device device) { + Position position = getPosition(device.getId()); + if (position != null) { + device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(this, position)); + } + } + } -- cgit v1.2.3 From 4dbe47a2362bde8e2a8419b202a02e5e7fc16f87 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 07:08:39 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 19 ------------------- src/main/java/org/traccar/Main.java | 3 ++- src/main/java/org/traccar/MainModule.java | 11 +++++++++++ .../java/org/traccar/broadcast/BroadcastService.java | 2 -- 4 files changed, 13 insertions(+), 22 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index dcbe6c811..1e158438f 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import org.apache.velocity.app.VelocityEngine; import org.eclipse.jetty.util.URIUtil; -import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -132,12 +131,6 @@ public final class Context { return webServer; } - private static BroadcastService broadcastService; - - public static BroadcastService getBroadcastService() { - return broadcastService; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -253,10 +246,6 @@ public final class Context { initEventsModule(); - if (config.hasKey(Keys.BROADCAST_ADDRESS)) { - broadcastService = new BroadcastService(config, objectMapper); - } - if (config.hasKey(Keys.EVENT_FORWARD_URL)) { eventForwarder = new EventForwarder(config); } @@ -288,14 +277,6 @@ public final class Context { velocityEngine.init(velocityProperties); } - public static void init(IdentityManager testIdentityManager) { - config = new Config(); - objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JSR353Module()); - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); - identityManager = testIdentityManager; - } - public static BaseObjectManager getManager(Class clazz) { if (clazz.equals(Device.class)) { return (BaseObjectManager) deviceManager; diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index b14f22a00..c35ea33a9 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -20,6 +20,7 @@ import com.google.inject.Injector; import com.google.inject.servlet.ServletModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; import java.io.File; @@ -122,7 +123,7 @@ public final class Main { services.add(injector.getInstance(ServerManager.class)); services.add(Context.getWebServer()); services.add(injector.getInstance(ScheduleManager.class)); - services.add(Context.getBroadcastService()); + services.add(injector.getInstance(BroadcastService.class)); for (LifecycleObject service : services) { if (service != null) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index bb264cff3..c9f2d4e62 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -21,6 +21,7 @@ import com.google.inject.Provides; import com.google.inject.Scopes; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; @@ -65,6 +66,7 @@ import org.traccar.storage.Storage; import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; +import java.io.IOException; public class MainModule extends AbstractModule { @@ -247,4 +249,13 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static BroadcastService provideBroadcastService( + Config config, ObjectMapper objectMapper) throws IOException { + if (config.hasKey(Keys.BROADCAST_ADDRESS)) { + return new BroadcastService(config, objectMapper); + } + return null; + } + } diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java index b17857fcd..26e38400b 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastService.java +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -22,7 +22,6 @@ import org.traccar.LifecycleObject; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -46,7 +45,6 @@ public class BroadcastService implements LifecycleObject { private final ExecutorService service = Executors.newSingleThreadExecutor(); private final byte[] receiverBuffer = new byte[4096]; - @Inject public BroadcastService(Config config, ObjectMapper objectMapper) throws IOException { this.objectMapper = objectMapper; address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); -- cgit v1.2.3 From 6f163bdf3856323a5aa075f9a2e1aeb01b7bc598 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 08:53:26 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 20 -------------------- src/main/java/org/traccar/MainModule.java | 6 ------ .../org/traccar/reports/StopsReportProvider.java | 7 +++++-- .../org/traccar/reports/TripsReportProvider.java | 7 +++++-- .../java/org/traccar/reports/common/TripsConfig.java | 20 +++++++++++++++++++- 5 files changed, 29 insertions(+), 31 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 1e158438f..46c761094 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -41,7 +41,6 @@ import org.traccar.model.Notification; import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; -import org.traccar.reports.common.TripsConfig; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; @@ -167,23 +166,6 @@ public final class Context { return smsManager; } - private static TripsConfig tripsConfig; - - public static TripsConfig getTripsConfig() { - return tripsConfig; - } - - public static TripsConfig initTripsConfig() { - return new TripsConfig( - config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DISTANCE), - config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DURATION) * 1000, - config.getLong(Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION) * 1000, - config.getLong(Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION) * 1000, - config.getBoolean(Keys.REPORT_TRIP_USE_IGNITION), - config.getBoolean(Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS), - config.getDouble(Keys.EVENT_MOTION_SPEED_THRESHOLD)); - } - private static class ObjectMapperContextResolver implements ContextResolver { @Override @@ -236,8 +218,6 @@ public final class Context { connectionManager = new ConnectionManager(); - tripsConfig = initTripsConfig(); - if (config.hasKey(Keys.SMS_HTTP_URL)) { smsManager = new HttpSmsClient(); } else if (config.hasKey(Keys.SMS_AWS_REGION)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index c9f2d4e62..d070c9fd7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -57,7 +57,6 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.reports.common.TripsConfig; import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; @@ -110,11 +109,6 @@ public class MainModule extends AbstractModule { return Context.getClient(); } - @Provides - public static TripsConfig provideTripsConfig() { - return Context.getTripsConfig(); - } - @Provides public static DeviceManager provideDeviceManager() { return Context.getDeviceManager(); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 8899dc42f..b7896c423 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -34,6 +34,7 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; import org.traccar.storage.Storage; @@ -45,11 +46,13 @@ public class StopsReportProvider { private final PermissionsService permissionsService; private final Storage storage; + private final TripsConfig tripsConfig; @Inject - public StopsReportProvider(PermissionsService permissionsService, Storage storage) { + public StopsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { this.permissionsService = permissionsService; this.storage = storage; + this.tripsConfig = tripsConfig; } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { @@ -61,7 +64,7 @@ public class StopsReportProvider { return ReportUtils.detectTripsAndStops( storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); + tripsConfig, ignoreOdometer, StopReportItem.class); } public Collection getObjects( diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index bcd79ab25..0505baaa1 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -33,6 +33,7 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; @@ -44,11 +45,13 @@ public class TripsReportProvider { private final PermissionsService permissionsService; private final Storage storage; + private final TripsConfig tripsConfig; @Inject - public TripsReportProvider(PermissionsService permissionsService, Storage storage) { + public TripsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { this.permissionsService = permissionsService; this.storage = storage; + this.tripsConfig = tripsConfig; } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { @@ -60,7 +63,7 @@ public class TripsReportProvider { return ReportUtils.detectTripsAndStops( storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); + tripsConfig, ignoreOdometer, TripReportItem.class); } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java index 9a7cebafb..c28cbeed4 100644 --- a/src/main/java/org/traccar/reports/common/TripsConfig.java +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -16,9 +16,27 @@ */ package org.traccar.reports.common; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; + public class TripsConfig { - public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, + @Inject + public TripsConfig(Config config) { + this( + config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DISTANCE), + config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DURATION) * 1000, + config.getLong(Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION) * 1000, + config.getLong(Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION) * 1000, + config.getBoolean(Keys.REPORT_TRIP_USE_IGNITION), + config.getBoolean(Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS), + config.getDouble(Keys.EVENT_MOTION_SPEED_THRESHOLD)); + } + + public TripsConfig( + double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; -- cgit v1.2.3 From 5b6bba55d960dcf4fc7721d1d2e75b950bb13809 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 16:22:40 -0700 Subject: Make singleton --- src/main/java/org/traccar/database/StatisticsManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index 3579ce7a5..d5a179cbe 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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. @@ -26,6 +26,7 @@ import org.traccar.model.Statistics; import org.traccar.storage.StorageException; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; @@ -37,6 +38,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +@Singleton public class StatisticsManager { private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsManager.class); -- cgit v1.2.3 From 29b5d05cfd66a9f51b7ce272c1fb07077bc715b2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 17:09:52 -0700 Subject: Remove WebServer from context --- src/main/java/org/traccar/Context.java | 11 ---------- src/main/java/org/traccar/Main.java | 32 ++++++++++++---------------- src/main/java/org/traccar/MainModule.java | 9 ++++++++ src/main/java/org/traccar/web/WebServer.java | 2 ++ 4 files changed, 25 insertions(+), 29 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 46c761094..3e4cc1bb9 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -46,7 +46,6 @@ import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; -import org.traccar.web.WebServer; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; @@ -124,12 +123,6 @@ public final class Context { return Main.getInjector() != null ? Main.getInjector().getInstance(Geocoder.class) : null; } - private static WebServer webServer; - - public static WebServer getWebServer() { - return webServer; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -210,10 +203,6 @@ public final class Context { identityManager = deviceManager; - if (config.hasKey(Keys.WEB_PORT)) { - webServer = new WebServer(config); - } - permissionsManager = new PermissionsManager(dataManager, usersManager); connectionManager = new ConnectionManager(); diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index c35ea33a9..412ac1f5e 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; +import org.traccar.web.WebServer; import java.io.File; import java.lang.management.ManagementFactory; @@ -29,10 +30,10 @@ import java.lang.management.MemoryMXBean; import java.lang.management.OperatingSystemMXBean; import java.lang.management.RuntimeMXBean; import java.nio.charset.Charset; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; import java.util.Locale; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; public final class Main { @@ -119,28 +120,23 @@ public final class Main { LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); - List services = new LinkedList<>(); - services.add(injector.getInstance(ServerManager.class)); - services.add(Context.getWebServer()); - services.add(injector.getInstance(ScheduleManager.class)); - services.add(injector.getInstance(BroadcastService.class)); + var services = Stream.of( + ServerManager.class, WebServer.class, ScheduleManager.class, BroadcastService.class) + .map(injector::getInstance) + .filter(Objects::nonNull) + .collect(Collectors.toList()); - for (LifecycleObject service : services) { - if (service != null) { - service.start(); - } + for (var service : services) { + service.start(); } Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.error("Thread exception", e)); Runtime.getRuntime().addShutdownHook(new Thread(() -> { - LOGGER.info("Shutting down server..."); + LOGGER.info("Stopping server..."); - Collections.reverse(services); - for (LifecycleObject service : services) { - if (service != null) { - service.stop(); - } + for (var service : services) { + service.stop(); } })); } catch (Exception e) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index d070c9fd7..9ec73d819 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -61,6 +61,7 @@ import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; +import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; @@ -128,6 +129,14 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static WebServer provideWebServer(Config config) { + if (config.hasKey(Keys.WEB_PORT)) { + return new WebServer(config); + } + return null; + } + @Singleton @Provides public static Geocoder provideGeocoder(Config config) { diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index f1ee8fcb2..fdbfc1464 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -60,6 +60,7 @@ import org.traccar.api.security.SecurityRequestFilter; import org.traccar.api.resource.ServerResource; import org.traccar.config.Keys; +import javax.inject.Inject; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; @@ -79,6 +80,7 @@ public class WebServer implements LifecycleObject { private final Server server; + @Inject public WebServer(Config config) { String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); -- cgit v1.2.3 From adafc5f6130854dd88c191dd04489073419ee41d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 17:56:37 -0700 Subject: Remove SMS from context --- src/main/java/org/traccar/BaseProtocol.java | 18 +++++-- src/main/java/org/traccar/Context.java | 15 ------ src/main/java/org/traccar/MainModule.java | 12 ++++- src/main/java/org/traccar/ServerManager.java | 6 ++- src/main/java/org/traccar/config/Keys.java | 8 ++++ .../traccar/notification/NotificatorManager.java | 56 ++++++++-------------- .../org/traccar/notificators/NotificatorSms.java | 24 +++++++--- 7 files changed, 74 insertions(+), 65 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index ec1933dc8..d19fc307e 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.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. @@ -21,7 +21,10 @@ import io.netty.channel.Channel; import io.netty.handler.codec.string.StringEncoder; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.sms.SmsManager; +import javax.annotation.Nullable; +import javax.inject.Inject; import java.net.SocketAddress; import java.util.Arrays; import java.util.Collection; @@ -37,6 +40,8 @@ public abstract class BaseProtocol implements Protocol { private final Set supportedTextCommands = new HashSet<>(); private final List connectorList = new LinkedList<>(); + private SmsManager smsManager; + private StringProtocolEncoder textCommandEncoder = null; public static String nameFromClass(Class clazz) { @@ -48,6 +53,11 @@ public abstract class BaseProtocol implements Protocol { name = nameFromClass(getClass()); } + @Inject + public void setSmsManager(@Nullable SmsManager smsManager) { + this.smsManager = smsManager; + } + @Override public String getName() { return name; @@ -111,13 +121,13 @@ public abstract class BaseProtocol implements Protocol { @Override public void sendTextCommand(String destAddress, Command command) throws Exception { - if (Context.getSmsManager() != null) { + if (smsManager != null) { if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmsManager().sendMessage(destAddress, command.getString(Command.KEY_DATA), true); + smsManager.sendMessage(destAddress, command.getString(Command.KEY_DATA), true); } else if (supportedTextCommands.contains(command.getType()) && textCommandEncoder != null) { String encodedCommand = (String) textCommandEncoder.encodeCommand(command); if (encodedCommand != null) { - Context.getSmsManager().sendMessage(destAddress, encodedCommand, true); + smsManager.sendMessage(destAddress, encodedCommand, true); } else { throw new RuntimeException("Failed to encode command"); } diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 3e4cc1bb9..5011764c6 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -43,9 +43,6 @@ import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; -import org.traccar.sms.HttpSmsClient; -import org.traccar.sms.SmsManager; -import org.traccar.sms.SnsSmsClient; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; @@ -153,12 +150,6 @@ public final class Context { return eventForwarder; } - private static SmsManager smsManager; - - public static SmsManager getSmsManager() { - return smsManager; - } - private static class ObjectMapperContextResolver implements ContextResolver { @Override @@ -207,12 +198,6 @@ public final class Context { connectionManager = new ConnectionManager(); - if (config.hasKey(Keys.SMS_HTTP_URL)) { - smsManager = new HttpSmsClient(); - } else if (config.hasKey(Keys.SMS_AWS_REGION)) { - smsManager = new SnsSmsClient(); - } - initEventsModule(); if (config.hasKey(Keys.EVENT_FORWARD_URL)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 9ec73d819..f6621a18e 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -57,7 +57,9 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; +import org.traccar.sms.SnsSmsClient; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; @@ -115,9 +117,15 @@ public class MainModule extends AbstractModule { return Context.getDeviceManager(); } + @Singleton @Provides - public static SmsManager provideSmsManager() { - return Context.getSmsManager(); + public static SmsManager provideSmsManager(Config config) { + if (config.hasKey(Keys.SMS_HTTP_URL)) { + return new HttpSmsClient(); + } else if (config.hasKey(Keys.SMS_AWS_REGION)) { + return new SnsSmsClient(); + } + return null; } @Singleton diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index a6bb6888c..f4f6e1ba4 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -15,11 +15,13 @@ */ package org.traccar; +import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Keys; import org.traccar.helper.ClassScanner; +import javax.inject.Inject; import javax.inject.Singleton; import java.io.IOException; import java.net.BindException; @@ -38,10 +40,12 @@ public class ServerManager implements LifecycleObject { private final List connectorList = new LinkedList<>(); private final Map protocolList = new ConcurrentHashMap<>(); - public ServerManager() throws IOException, URISyntaxException, ReflectiveOperationException { + @Inject + public ServerManager(Injector injector) throws IOException, URISyntaxException, ReflectiveOperationException { for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { if (Context.getConfig().hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); + injector.injectMembers(protocol); connectorList.addAll(protocol.getConnectorList()); protocolList.put(protocol.getName(), protocol); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ba576397b..d53245c65 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -753,6 +753,14 @@ public final class Keys { "sms.aws.region", Collections.singletonList(KeyType.GLOBAL)); + /** + * Enabled notification options. Comma-separated string is expected. + * Example: web,mail,sms + */ + public static final ConfigKey NOTIFICATOR_TYPES = new ConfigKey<>( + "notificator.types", + Collections.singletonList(KeyType.GLOBAL)); + /** * Traccar notification API key. */ diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index dfd8cd3d6..9705377b4 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 - 2020 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"); @@ -24,6 +24,8 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; +import org.traccar.config.Keys; import org.traccar.model.Typed; import org.traccar.notificators.NotificatorFirebase; import org.traccar.notificators.NotificatorMail; @@ -39,45 +41,25 @@ public final class NotificatorManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorManager.class); - private static final Notificator NULL_NOTIFICATOR = new NotificatorNull(); + private static final Map> NOTIFICATORS_ALL = Map.of( + "web", NotificatorWeb.class, + "mail", NotificatorMail.class, + "sms", NotificatorSms.class, + "firebase", NotificatorFirebase.class, + "traccar", NotificatorTraccar.class, + "telegram", NotificatorTelegram.class, + "pushover", NotificatorPushover.class); private final Map notificators = new HashMap<>(); public NotificatorManager() { - final String[] types = Context.getConfig().getString("notificator.types", "").split(","); - for (String type : types) { - String defaultNotificator = ""; - switch (type) { - case "web": - defaultNotificator = NotificatorWeb.class.getCanonicalName(); - break; - case "mail": - defaultNotificator = NotificatorMail.class.getCanonicalName(); - break; - case "sms": - defaultNotificator = NotificatorSms.class.getCanonicalName(); - break; - case "firebase": - defaultNotificator = NotificatorFirebase.class.getCanonicalName(); - break; - case "traccar": - defaultNotificator = NotificatorTraccar.class.getCanonicalName(); - break; - case "telegram": - defaultNotificator = NotificatorTelegram.class.getCanonicalName(); - break; - case "pushover": - defaultNotificator = NotificatorPushover.class.getCanonicalName(); - break; - default: - break; - } - final String className = Context.getConfig() - .getString("notificator." + type + ".class", defaultNotificator); - try { - notificators.put(type, (Notificator) Class.forName(className).newInstance()); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { - LOGGER.warn("Unable to load notificator class for " + type + " " + className + " " + e.getMessage()); + String types = Context.getConfig().getString(Keys.NOTIFICATOR_TYPES); + if (types != null) { + for (String type : types.split(",")) { + var notificatorClass = NOTIFICATORS_ALL.get(type); + if (notificatorClass != null) { + notificators.put(type, Main.getInjector().getInstance(notificatorClass)); + } } } } @@ -86,7 +68,7 @@ public final class NotificatorManager { final Notificator notificator = notificators.get(type); if (notificator == null) { LOGGER.warn("No notificator configured for type : " + type); - return NULL_NOTIFICATOR; + return new NotificatorNull(); } return notificator; } diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index f35b797cd..f4d1de0cb 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -16,8 +16,6 @@ */ package org.traccar.notificators; -import org.traccar.Context; -import org.traccar.Main; import org.traccar.database.StatisticsManager; import org.traccar.model.Event; import org.traccar.model.Position; @@ -26,16 +24,30 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; +import org.traccar.sms.SmsManager; -public final class NotificatorSms implements Notificator { +import javax.inject.Inject; + +public class NotificatorSms implements Notificator { + + private final SmsManager smsManager; + private final CacheManager cacheManager; + private final StatisticsManager statisticsManager; + + @Inject + public NotificatorSms(SmsManager smsManager, CacheManager cacheManager, StatisticsManager statisticsManager) { + this.smsManager = smsManager; + this.cacheManager = cacheManager; + this.statisticsManager = statisticsManager; + } @Override public void send(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); - Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - Context.getSmsManager().sendMessage(user.getPhone(), shortMessage.getBody(), false); + cacheManager, user, event, position, "short"); + statisticsManager.registerSms(); + smsManager.sendMessage(user.getPhone(), shortMessage.getBody(), false); } } -- cgit v1.2.3 From 336d6c4353fd77ad268aaf5cfe9c0296edfb0201 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 18:03:52 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 12 ++++-------- .../org/traccar/api/resource/NotificationResource.java | 14 +++++++++----- .../java/org/traccar/database/NotificationManager.java | 8 ++++++-- .../java/org/traccar/notification/NotificatorManager.java | 13 +++++++++---- 4 files changed, 28 insertions(+), 19 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 5011764c6..42a92f436 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -126,12 +126,6 @@ public final class Context { return notificationManager; } - private static NotificatorManager notificatorManager; - - public static NotificatorManager getNotificatorManager() { - return notificatorManager; - } - private static VelocityEngine velocityEngine; public static VelocityEngine getVelocityEngine() { @@ -208,8 +202,10 @@ public final class Context { private static void initEventsModule() { - notificationManager = new NotificationManager(dataManager, Main.getInjector().getInstance(CacheManager.class)); - notificatorManager = new NotificatorManager(); + notificationManager = new NotificationManager( + dataManager, + Main.getInjector().getInstance(CacheManager.class), + Main.getInjector().getInstance(NotificatorManager.class)); Properties velocityProperties = new Properties(); velocityProperties.setProperty("file.resource.loader.path", Context.getConfig().getString("templates.rootPath", "templates") + "/"); diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 9ea811473..0a95b257a 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import java.util.Collection; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -33,6 +34,7 @@ import org.traccar.model.Notification; import org.traccar.model.Typed; import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.notification.NotificatorManager; import org.traccar.storage.StorageException; @Path("notifications") @@ -40,6 +42,9 @@ import org.traccar.storage.StorageException; @Consumes(MediaType.APPLICATION_JSON) public class NotificationResource extends ExtendedObjectResource { + @Inject + private NotificatorManager notificatorManager; + public NotificationResource() { super(Notification.class); } @@ -53,16 +58,15 @@ public class NotificationResource extends ExtendedObjectResource { @GET @Path("notificators") public Collection getNotificators() { - return Context.getNotificatorManager().getAllNotificatorTypes(); + return notificatorManager.getAllNotificatorTypes(); } @POST @Path("test") public Response testMessage() throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); - for (Typed method : Context.getNotificatorManager().getAllNotificatorTypes()) { - Context.getNotificatorManager() - .getNotificator(method.getType()).send(user, new Event("test", 0), null); + for (Typed method : notificatorManager.getAllNotificatorTypes()) { + notificatorManager.getNotificator(method.getType()).send(user, new Event("test", 0), null); } return Response.noContent().build(); } @@ -72,7 +76,7 @@ public class NotificationResource extends ExtendedObjectResource { public Response testMessage(@PathParam("notificator") String notificator) throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); - Context.getNotificatorManager().getNotificator(notificator).send(user, new Event("test", 0), null); + notificatorManager.getNotificator(notificator).send(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 fcefb54f0..eddd7e2b4 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -37,6 +37,7 @@ import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; @@ -45,12 +46,15 @@ public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); private final CacheManager cacheManager; + private final NotificatorManager notificatorManager; private final boolean geocodeOnRequest; - public NotificationManager(DataManager dataManager, CacheManager cacheManager) { + public NotificationManager( + DataManager dataManager, CacheManager cacheManager, NotificatorManager notificatorManager) { super(dataManager, Notification.class); this.cacheManager = cacheManager; + this.notificatorManager = notificatorManager; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); } @@ -116,7 +120,7 @@ public class NotificationManager extends ExtendedObjectManager { new Thread(() -> { for (String notificator : notificators) { try { - Context.getNotificatorManager().getNotificator(notificator).send(user, event, position); + notificatorManager.getNotificator(notificator).send(user, event, position); } catch (MessageException | InterruptedException 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 9705377b4..d6ebb2c4a 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -23,8 +23,8 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Typed; import org.traccar.notificators.NotificatorFirebase; @@ -37,7 +37,11 @@ import org.traccar.notificators.NotificatorWeb; import org.traccar.notificators.NotificatorTelegram; import org.traccar.notificators.NotificatorPushover; -public final class NotificatorManager { +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class NotificatorManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorManager.class); @@ -52,8 +56,9 @@ public final class NotificatorManager { private final Map notificators = new HashMap<>(); - public NotificatorManager() { - String types = Context.getConfig().getString(Keys.NOTIFICATOR_TYPES); + @Inject + public NotificatorManager(Config config) { + String types = config.getString(Keys.NOTIFICATOR_TYPES); if (types != null) { for (String type : types.split(",")) { var notificatorClass = NOTIFICATORS_ALL.get(type); -- cgit v1.2.3 From c03b4a2ace925e6a0d7c43ce59e14ddb9cbf18a9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 07:06:43 -0700 Subject: Inject mail manager --- src/main/java/org/traccar/Context.java | 9 --------- .../org/traccar/api/resource/PasswordResource.java | 7 ++++++- .../java/org/traccar/api/resource/ReportResource.java | 8 +++++--- .../java/org/traccar/api/resource/ServerResource.java | 8 +++++++- src/main/java/org/traccar/database/MailManager.java | 16 ++++++++++++---- src/main/java/org/traccar/model/Server.java | 10 ++++++++-- .../org/traccar/notificators/NotificatorMail.java | 19 ++++++++++++++----- 7 files changed, 52 insertions(+), 25 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 42a92f436..cba4c0a58 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -27,7 +27,6 @@ import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; -import org.traccar.database.MailManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; @@ -80,12 +79,6 @@ public final class Context { return dataManager; } - private static MailManager mailManager; - - public static MailManager getMailManager() { - return mailManager; - } - private static UsersManager usersManager; public static UsersManager getUsersManager() { @@ -178,8 +171,6 @@ public final class Context { dataManager = new DataManager(config); } - mailManager = new MailManager(); - if (dataManager != null) { usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 91d994153..7df25c264 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -18,12 +18,14 @@ package org.traccar.api.resource; import org.apache.velocity.VelocityContext; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.MailManager; import org.traccar.model.User; import org.traccar.notification.NotificationMessage; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.mail.MessagingException; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; @@ -41,6 +43,9 @@ public class PasswordResource extends BaseResource { private static final String PASSWORD_RESET_TOKEN = "passwordToken"; + @Inject + private MailManager mailManager; + @Path("reset") @PermitAll @POST @@ -56,7 +61,7 @@ public class PasswordResource extends BaseResource { velocityContext.put("token", token); NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); + mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); break; } } diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 3c1b8f715..3955f1d20 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -38,8 +38,8 @@ import javax.ws.rs.core.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.MailManager; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; @@ -80,6 +80,9 @@ public class ReportResource extends BaseResource { @Inject private TripsReportProvider tripsReportProvider; + @Inject + private MailManager mailManager; + private interface ReportExecutor { void execute(ByteArrayOutputStream stream) throws StorageException, IOException; } @@ -99,8 +102,7 @@ public class ReportResource extends BaseResource { stream.toByteArray(), "application/octet-stream"))); User user = permissionsService.getUser(userId); - Context.getMailManager().sendMessage( - user, "Report", "The report is in the attachment.", attachment); + mailManager.sendMessage(user, "Report", "The report is in the attachment.", attachment); } catch (StorageException | IOException | MessagingException e) { LOGGER.warn("Report failed", e); } diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index f238e8905..51a26825b 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.MailManager; import org.traccar.helper.LogAction; import org.traccar.model.Server; import org.traccar.storage.Storage; @@ -46,10 +47,15 @@ public class ServerResource extends BaseResource { @Inject private Storage storage; + @Inject + private MailManager mailManager; + @PermitAll @GET public Server get() throws StorageException { - return storage.getObject(Server.class, new Request(new Columns.All())); + Server server = storage.getObject(Server.class, new Request(new Columns.All())); + server.setEmailEnabled(mailManager.getEmailEnabled()); + return server; } @PUT diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 21fee5ee7..54f617d5f 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -18,11 +18,12 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; +import javax.inject.Inject; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; @@ -40,6 +41,13 @@ public final class MailManager { private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); + private final Config config; + + @Inject + public MailManager(Config config) { + this.config = config; + } + private static Properties getProperties(PropertiesProvider provider) { Properties properties = new Properties(); String host = provider.getString("mail.smtp.host"); @@ -88,7 +96,7 @@ public final class MailManager { } public boolean getEmailEnabled() { - return Context.getConfig().hasKey("mail.smtp.host"); + return config.hasKey("mail.smtp.host"); } public void sendMessage( @@ -99,11 +107,11 @@ public final class MailManager { public void sendMessage( User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { Properties properties = null; - if (!Context.getConfig().getBoolean("mail.smtp.ignoreUserConfig")) { + if (!config.getBoolean("mail.smtp.ignoreUserConfig")) { properties = getProperties(new PropertiesProvider(user)); } if (properties == null || !properties.containsKey("mail.smtp.host")) { - properties = getProperties(new PropertiesProvider(Context.getConfig())); + properties = getProperties(new PropertiesProvider(config)); } if (!properties.containsKey("mail.smtp.host")) { LOGGER.warn("No SMTP configuration found"); diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 7cffd7eac..c5640fb97 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -16,7 +16,6 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.traccar.Context; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -193,9 +192,16 @@ public class Server extends ExtendedModel implements UserRestrictions { return getClass().getPackage().getImplementationVersion(); } + private boolean emailEnabled; + + @QueryIgnore + public void setEmailEnabled(boolean emailEnabled) { + this.emailEnabled = emailEnabled; + } + @QueryIgnore public Boolean getEmailEnabled() { - return Context.getMailManager().getEmailEnabled(); + return emailEnabled; } } diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index fd7cae7c3..fe8d69af2 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -16,8 +16,7 @@ */ package org.traccar.notificators; -import org.traccar.Context; -import org.traccar.Main; +import org.traccar.database.MailManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; @@ -26,16 +25,26 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; import javax.mail.MessagingException; -public final class NotificatorMail implements Notificator { +public class NotificatorMail implements Notificator { + + private final MailManager mailManager; + private final CacheManager cacheManager; + + @Inject + public NotificatorMail(MailManager mailManager, CacheManager cacheManager) { + this.mailManager = mailManager; + this.cacheManager = cacheManager; + } @Override public void send(User user, Event event, Position position) throws MessageException { try { NotificationMessage fullMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "full"); - Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); + cacheManager, user, event, position, "full"); + mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); } -- cgit v1.2.3 From bbe84d6a751fdc840e4201ef9027a96527006049 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 07:56:49 -0700 Subject: Inject report utils --- src/main/java/org/traccar/Context.java | 7 +- .../org/traccar/api/resource/ServerResource.java | 10 +- .../org/traccar/database/NotificationManager.java | 14 +- .../traccar/handler/events/MotionEventHandler.java | 11 +- .../org/traccar/helper/model/PositionUtil.java | 13 ++ .../org/traccar/reports/EventsReportProvider.java | 64 ++++---- .../org/traccar/reports/RouteReportProvider.java | 43 +++--- .../org/traccar/reports/StopsReportProvider.java | 62 +++----- .../org/traccar/reports/SummaryReportProvider.java | 43 +++--- .../org/traccar/reports/TripsReportProvider.java | 54 +++---- .../org/traccar/reports/common/ReportUtils.java | 165 +++++++++++---------- .../java/org/traccar/reports/ReportUtilsTest.java | 78 ++++++---- 12 files changed, 282 insertions(+), 282 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index cba4c0a58..471416926 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -109,10 +109,6 @@ public final class Context { return permissionsManager; } - public static Geocoder getGeocoder() { - return Main.getInjector() != null ? Main.getInjector().getInstance(Geocoder.class) : null; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -196,7 +192,8 @@ public final class Context { notificationManager = new NotificationManager( dataManager, Main.getInjector().getInstance(CacheManager.class), - Main.getInjector().getInstance(NotificatorManager.class)); + Main.getInjector().getInstance(NotificatorManager.class), + Main.getInjector().getInstance(Geocoder.class)); Properties velocityProperties = new Properties(); velocityProperties.setProperty("file.resource.loader.path", Context.getConfig().getString("templates.rootPath", "templates") + "/"); diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 51a26825b..18230a2b3 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; +import org.traccar.geocoder.Geocoder; import org.traccar.helper.LogAction; import org.traccar.model.Server; import org.traccar.storage.Storage; @@ -25,6 +26,7 @@ import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; +import javax.annotation.Nullable; import javax.annotation.security.PermitAll; import javax.inject.Inject; import javax.ws.rs.Consumes; @@ -50,6 +52,10 @@ public class ServerResource extends BaseResource { @Inject private MailManager mailManager; + @Inject + @Nullable + private Geocoder geocoder; + @PermitAll @GET public Server get() throws StorageException { @@ -69,8 +75,8 @@ public class ServerResource extends BaseResource { @Path("geocode") @GET public String geocode(@QueryParam("latitude") double latitude, @QueryParam("longitude") double longitude) { - if (Context.getGeocoder() != null) { - return Context.getGeocoder().getAddress(latitude, longitude, null); + if (geocoder != null) { + return geocoder.getAddress(latitude, longitude, null); } else { throw new RuntimeException("Reverse geocoding is not enabled"); } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index eddd7e2b4..1f4a48ac0 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -30,6 +30,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Keys; +import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; import org.traccar.model.Event; import org.traccar.model.Notification; @@ -41,20 +42,25 @@ import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import javax.annotation.Nullable; + public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); private final CacheManager cacheManager; private final NotificatorManager notificatorManager; + private final Geocoder geocoder; private final boolean geocodeOnRequest; public NotificationManager( - DataManager dataManager, CacheManager cacheManager, NotificatorManager notificatorManager) { + DataManager dataManager, CacheManager cacheManager, + NotificatorManager notificatorManager, @Nullable Geocoder geocoder) { super(dataManager, Notification.class); this.cacheManager = cacheManager; this.notificatorManager = notificatorManager; + this.geocoder = geocoder; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); } @@ -110,10 +116,8 @@ public class NotificationManager extends ExtendedObjectManager { } } - if (position != null && position.getAddress() == null - && geocodeOnRequest && Context.getGeocoder() != null) { - position.setAddress(Context.getGeocoder() - .getAddress(position.getLatitude(), position.getLongitude(), null)); + if (position != null && position.getAddress() == null && geocodeOnRequest && geocoder != null) { + position.setAddress(geocoder.getAddress(position.getLatitude(), position.getLongitude(), null)); } User user = Context.getUsersManager().getById(userId); diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 57d2bc1c5..2c381e530 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -16,20 +16,19 @@ */ package org.traccar.handler.events; -import java.util.Collections; -import java.util.Map; - import io.netty.channel.ChannelHandler; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; -import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.common.ReportUtils; import org.traccar.reports.common.TripsConfig; +import org.traccar.session.DeviceState; import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { @@ -89,7 +88,7 @@ public class MotionEventHandler extends BaseEventHandler { Position motionPosition = deviceState.getMotionPosition(); if (motionPosition != null) { long motionTime = motionPosition.getFixTime().getTime(); - double distance = ReportUtils.calculateDistance(motionPosition, position, false); + double distance = PositionUtil.calculateDistance(motionPosition, position, false); Boolean ignition = null; if (tripsConfig.getUseIgnition() && position.getAttributes().containsKey(Position.KEY_IGNITION)) { diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 64216a937..644517dac 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -28,4 +28,17 @@ public final class PositionUtil { return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; } + public static double calculateDistance(Position first, Position last, boolean useOdometer) { + double distance; + double firstOdometer = first.getDouble(Position.KEY_ODOMETER); + double lastOdometer = last.getDouble(Position.KEY_ODOMETER); + + if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { + distance = lastOdometer - firstOdometer; + } else { + distance = last.getDouble(Position.KEY_TOTAL_DISTANCE) - first.getDouble(Position.KEY_TOTAL_DISTANCE); + } + return distance; + } + } diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index f0c8c31b6..6de313a13 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -16,19 +16,8 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -36,28 +25,34 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; public class EventsReportProvider { - private final PermissionsService permissionsService; - private final Storage storage; + private final ReportUtils reportUtils; @Inject - public EventsReportProvider(PermissionsService permissionsService, Storage storage) { - this.permissionsService = permissionsService; - this.storage = storage; + public EventsReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = Context.getDataManager().getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); @@ -65,9 +60,9 @@ public class EventsReportProvider { if (all || types.contains(event.getType())) { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); - if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) + if ((geofenceId == 0 || reportUtils.getObject(userId, Geofence.class, geofenceId) != null) && (maintenanceId == 0 - || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { + || reportUtils.getObject(userId, Maintenance.class, maintenanceId) != null)) { result.add(event); } } @@ -79,12 +74,12 @@ public class EventsReportProvider { public void getExcel( OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = Context.getDataManager().getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); @@ -94,16 +89,14 @@ public class EventsReportProvider { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); if (geofenceId != 0) { - Geofence geofence = ReportUtils.getObject( - storage, userId, Geofence.class, geofenceId); + Geofence geofence = reportUtils.getObject(userId, Geofence.class, geofenceId); if (geofence != null) { geofenceNames.put(geofenceId, geofence.getName()); } else { iterator.remove(); } } else if (maintenanceId != 0) { - Maintenance maintenance = ReportUtils.getObject( - storage, userId, Maintenance.class, maintenanceId); + Maintenance maintenance = reportUtils.getObject(userId, Maintenance.class, maintenanceId); if (maintenance != null) { maintenanceNames.put(maintenanceId, maintenance.getName()); } else { @@ -130,15 +123,14 @@ public class EventsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesEvents); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("geofenceNames", geofenceNames); - jxlsContext.putVar("maintenanceNames", maintenanceNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesEvents); + context.putVar("sheetNames", sheetNames); + context.putVar("geofenceNames", geofenceNames); + context.putVar("maintenanceNames", maintenanceNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } } diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index e20ba6885..136a154aa 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -16,17 +16,8 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; @@ -35,21 +26,28 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; public class RouteReportProvider { - private final PermissionsService permissionsService; + private final ReportUtils reportUtils; @Inject - public RouteReportProvider(PermissionsService permissionsService) { - this.permissionsService = permissionsService; + public RouteReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); } @@ -59,10 +57,10 @@ public class RouteReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection positions = Context.getDataManager() .getPositions(deviceId, from, to); @@ -82,13 +80,12 @@ public class RouteReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesRoutes); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesRoutes); + context.putVar("sheetNames", sheetNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } } diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index b7896c423..807a6133b 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -14,65 +14,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.Main; -import org.traccar.api.security.PermissionsService; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; public class StopsReportProvider { - private final PermissionsService permissionsService; - private final Storage storage; - private final TripsConfig tripsConfig; + private final ReportUtils reportUtils; @Inject - public StopsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { - this.permissionsService = permissionsService; - this.storage = storage; - this.tripsConfig = tripsConfig; + public StopsReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - tripsConfig, ignoreOdometer, StopReportItem.class); + return reportUtils.detectTripsAndStops( + Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, StopReportItem.class); } public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectStops(deviceId, from, to)); } @@ -82,10 +65,10 @@ public class StopsReportProvider { public void getExcel( OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection stops = detectStops(deviceId, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); @@ -104,13 +87,12 @@ public class StopsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesStops); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesStops); + context.putVar("sheetNames", sheetNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 27dc5819d..28abe790b 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -16,19 +16,11 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; - import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; @@ -36,13 +28,23 @@ import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; public class SummaryReportProvider { + private final ReportUtils reportUtils; private final PermissionsService permissionsService; @Inject - public SummaryReportProvider(PermissionsService permissionsService) { + public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService) { + this.reportUtils = reportUtils; this.permissionsService = permissionsService; } @@ -64,8 +66,8 @@ public class SummaryReportProvider { } boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); - result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); + result.setDistance(PositionUtil.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); + result.setSpentFuel(reportUtils.calculateFuel(firstPosition, previousPosition)); long durationMilliseconds; if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) @@ -134,9 +136,9 @@ public class SummaryReportProvider { public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { @@ -151,18 +153,17 @@ public class SummaryReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("summaries", summaries); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); + var context = reportUtils.initializeContext(userId); + context.putVar("summaries", summaries); + context.putVar("from", from); + context.putVar("to", to); JxlsHelper.getInstance().setUseFastFormulaProcessor(false) - .processTemplate(inputStream, outputStream, jxlsContext); + .processTemplate(inputStream, outputStream, context); } } } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 0505baaa1..5e598cb50 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -16,42 +16,34 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; -import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; public class TripsReportProvider { - private final PermissionsService permissionsService; - private final Storage storage; - private final TripsConfig tripsConfig; + private final ReportUtils reportUtils; @Inject - public TripsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { - this.permissionsService = permissionsService; - this.storage = storage; - this.tripsConfig = tripsConfig; + public TripsReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { @@ -61,16 +53,15 @@ public class TripsReportProvider { IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - return ReportUtils.detectTripsAndStops( - storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - tripsConfig, ignoreOdometer, TripReportItem.class); + return reportUtils.detectTripsAndStops( + Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, TripReportItem.class); } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectTrips(deviceId, from, to)); } @@ -80,10 +71,10 @@ public class TripsReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection trips = detectTrips(deviceId, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); @@ -102,13 +93,12 @@ public class TripsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesTrips); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesTrips); + context.putVar("sheetNames", sheetNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 36d5c0fb1..706475241 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -26,28 +26,33 @@ import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.geocoder.Geocoder; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; -import org.traccar.model.Server; -import org.traccar.model.User; -import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; +import org.traccar.session.DeviceState; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.annotation.Nullable; +import javax.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -61,13 +66,31 @@ import java.util.List; import java.util.Locale; import java.util.Map; -public final class ReportUtils { - - private ReportUtils() { +public class ReportUtils { + + private final Config config; + private final Storage storage; + private final PermissionsService permissionsService; + private final IdentityManager identityManager; + private final DeviceManager deviceManager; + private final TripsConfig tripsConfig; + private final Geocoder geocoder; + + @Inject + public ReportUtils( + Config config, Storage storage, PermissionsService permissionsService, IdentityManager identityManager, + DeviceManager deviceManager, TripsConfig tripsConfig, @Nullable Geocoder geocoder) { + this.config = config; + this.storage = storage; + this.permissionsService = permissionsService; + this.identityManager = identityManager; + this.deviceManager = deviceManager; + this.tripsConfig = tripsConfig; + this.geocoder = geocoder; } - public static T getObject( - Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { + public T getObject( + long userId, Class clazz, long objectId) throws StorageException, SecurityException { return storage.getObject(clazz, new Request( new Columns.Include("id"), new Condition.And( @@ -75,14 +98,14 @@ public final class ReportUtils { new Condition.Permission(User.class, userId, clazz)))); } - public static void checkPeriodLimit(Date from, Date to) { - long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; + public void checkPeriodLimit(Date from, Date to) { + long limit = config.getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { throw new IllegalArgumentException("Time period exceeds the limit"); } } - public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { + public Collection getDeviceList(Collection deviceIds, Collection groupIds) { Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); @@ -90,26 +113,7 @@ public final class ReportUtils { return result; } - public static double calculateDistance(Position firstPosition, Position lastPosition) { - return calculateDistance(firstPosition, lastPosition, true); - } - - public static double calculateDistance(Position firstPosition, Position lastPosition, boolean useOdometer) { - double distance = 0.0; - double firstOdometer = firstPosition.getDouble(Position.KEY_ODOMETER); - double lastOdometer = lastPosition.getDouble(Position.KEY_ODOMETER); - - if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { - distance = lastOdometer - firstOdometer; - } else if (firstPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE) - && lastPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE)) { - distance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE) - - firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE); - } - return distance; - } - - public static double calculateFuel(Position firstPosition, Position lastPosition) { + public double calculateFuel(Position firstPosition, Position lastPosition) { if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null && lastPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null) { @@ -121,7 +125,7 @@ public final class ReportUtils { return 0; } - public static String findDriver(Position firstPosition, Position lastPosition) { + public String findDriver(Position firstPosition, Position lastPosition) { if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { @@ -130,7 +134,7 @@ public final class ReportUtils { return null; } - public static String findDriverName(Storage storage, String driverUniqueId) throws StorageException { + public String findDriverName(String driverUniqueId) throws StorageException { if (driverUniqueId != null) { Driver driver = storage.getObject(Driver.class, new Request( new Columns.All(), @@ -142,28 +146,29 @@ public final class ReportUtils { return null; } - public static org.jxls.common.Context initializeContext(Server server, User user) { - org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); - jxlsContext.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); - jxlsContext.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); - jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); - jxlsContext.putVar("dateTool", new DateTool()); - jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", UserUtil.getTimezone(server, user)); - jxlsContext.putVar("locale", Locale.getDefault()); - jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); - return jxlsContext; + public org.jxls.common.Context initializeContext(long userId) throws StorageException { + var server = permissionsService.getServer(); + var user = permissionsService.getUser(userId); + var context = PoiTransformer.createInitialContext(); + context.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); + context.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); + context.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); + context.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); + context.putVar("dateTool", new DateTool()); + context.putVar("numberTool", new NumberTool()); + context.putVar("timezone", UserUtil.getTimezone(server, user)); + context.putVar("locale", Locale.getDefault()); + context.putVar("bracketsRegex", "[\\{\\}\"]"); + return context; } - public static void processTemplateWithSheets( - InputStream templateStream, OutputStream targetStream, - org.jxls.common.Context jxlsContext) throws IOException { + public void processTemplateWithSheets( + InputStream templateStream, OutputStream targetStream, org.jxls.common.Context context) throws IOException { Transformer transformer = TransformerFactory.createTransformer(templateStream, targetStream); List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); for (Area xlsArea : xlsAreas) { - xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext); + xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), context); xlsArea.setFormulaProcessor(new StandardFormulaProcessor()); xlsArea.processFormulas(); } @@ -171,9 +176,9 @@ public final class ReportUtils { transformer.write(); } - private static TripReportItem calculateTrip( - Storage storage, IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) throws StorageException { + private TripReportItem calculateTrip( + ArrayList positions, int startIndex, int endIndex, + boolean ignoreOdometer) throws StorageException { Position startTrip = positions.get(startIndex); Position endTrip = positions.get(endIndex); @@ -198,9 +203,8 @@ public final class ReportUtils { trip.setStartLon(startTrip.getLongitude()); trip.setStartTime(startTrip.getFixTime()); String startAddress = startTrip.getAddress(); - if (startAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - startAddress = Context.getGeocoder().getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); + if (startAddress == null && geocoder != null && config.getBoolean(Keys.GEOCODER_ON_REQUEST)) { + startAddress = geocoder.getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); } trip.setStartAddress(startAddress); @@ -209,13 +213,12 @@ public final class ReportUtils { trip.setEndLon(endTrip.getLongitude()); trip.setEndTime(endTrip.getFixTime()); String endAddress = endTrip.getAddress(); - if (endAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - endAddress = Context.getGeocoder().getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); + if (endAddress == null && geocoder != null && config.getBoolean(Keys.GEOCODER_ON_REQUEST)) { + endAddress = geocoder.getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); } trip.setEndAddress(endAddress); - trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer)); + trip.setDistance(PositionUtil.calculateDistance(startTrip, endTrip, !ignoreOdometer)); trip.setDuration(tripDuration); if (tripDuration > 0) { trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); @@ -224,7 +227,7 @@ public final class ReportUtils { trip.setSpentFuel(calculateFuel(startTrip, endTrip)); trip.setDriverUniqueId(findDriver(startTrip, endTrip)); - trip.setDriverName(findDriverName(storage, trip.getDriverUniqueId())); + trip.setDriverName(findDriverName(trip.getDriverUniqueId())); if (!ignoreOdometer && startTrip.getDouble(Position.KEY_ODOMETER) != 0 @@ -239,9 +242,8 @@ public final class ReportUtils { return trip; } - private static StopReportItem calculateStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { + private StopReportItem calculateStop( + ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -257,9 +259,8 @@ public final class ReportUtils { stop.setLongitude(startStop.getLongitude()); stop.setStartTime(startStop.getFixTime()); String address = startStop.getAddress(); - if (address == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - address = Context.getGeocoder().getAddress(stop.getLatitude(), stop.getLongitude(), null); + if (address == null && geocoder != null && config.getBoolean(Keys.GEOCODER_ON_REQUEST)) { + address = geocoder.getAddress(stop.getLatitude(), stop.getLongitude(), null); } stop.setAddress(address); @@ -288,18 +289,19 @@ public final class ReportUtils { } - private static T calculateTripOrStop( - Storage storage, IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) throws StorageException { + @SuppressWarnings("unchecked") + private T calculateTripOrStop( + ArrayList positions, int startIndex, int endIndex, + boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - return (T) calculateTrip(storage, identityManager, positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); } else { - return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); } } - private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { + private boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { if (tripsConfig.getMinimalNoDataDuration() > 0) { boolean beforeGap = index < positions.size() - 1 && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() @@ -319,17 +321,16 @@ public final class ReportUtils { } } - public static Collection detectTripsAndStops( - Storage storage, IdentityManager identityManager, DeviceManager deviceManager, - Collection positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) throws StorageException { + public Collection detectTripsAndStops( + Collection positionCollection, boolean ignoreOdometer, + Class reportClass) throws StorageException { Collection result = new ArrayList<>(); ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); + MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; @@ -355,15 +356,15 @@ public final class ReportUtils { } if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(storage, identityManager, positions, - startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + result.add(calculateTripOrStop( + positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(storage, identityManager, positions, - startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, - ignoreOdometer, reportClass)); + int endIndex = startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1; + result.add(calculateTripOrStop( + positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); } } diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 9b287a0fd..92bfdae1c 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -2,7 +2,11 @@ package org.traccar.reports; import org.junit.Test; import org.traccar.BaseTest; +import org.traccar.api.security.PermissionsService; +import org.traccar.config.Config; +import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; @@ -63,20 +67,23 @@ public class ReportUtilsTest extends BaseTest { startPosition.set(Position.KEY_TOTAL_DISTANCE, 500.0); Position endPosition = new Position(); endPosition.set(Position.KEY_TOTAL_DISTANCE, 700.0); - assertEquals(ReportUtils.calculateDistance(startPosition, endPosition), 200.0, 10); + assertEquals(PositionUtil.calculateDistance(startPosition, endPosition, true), 200.0, 10); startPosition.set(Position.KEY_ODOMETER, 50000); endPosition.set(Position.KEY_ODOMETER, 51000); - assertEquals(ReportUtils.calculateDistance(startPosition, endPosition), 1000.0, 10); + assertEquals(PositionUtil.calculateDistance(startPosition, endPosition, true), 1000.0, 10); } @Test public void testCalculateSpentFuel() { + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), mock(TripsConfig.class), null); Position startPosition = new Position(); Position endPosition = new Position(); - assertEquals(ReportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); + assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); startPosition.set(Position.KEY_FUEL_LEVEL, 0.7); endPosition.set(Position.KEY_FUEL_LEVEL, 0.5); - assertEquals(ReportUtils.calculateFuel(startPosition, endPosition), 0.2, 0.01); + assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.2, 0.01); } @Test @@ -93,9 +100,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:07:00.000", 0, 3000)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -109,8 +118,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -147,9 +155,11 @@ public class ReportUtilsTest extends BaseTest { data.get(5).set(Position.KEY_IGNITION, false); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -163,8 +173,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -178,8 +187,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -218,9 +226,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:11:00.000", 0, 7000)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -234,8 +244,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -268,9 +277,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 0, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -295,9 +306,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 2, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -322,9 +335,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 0, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -349,9 +364,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 5, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -372,9 +389,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:25:00.000", 5, 900)); TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -388,8 +407,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From fe61a79b37a2de3bc435890e5cca43ac05fc598c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 08:19:27 -0700 Subject: Full injection for notificators --- .../traccar/notificators/NotificatorFirebase.java | 39 ++++++----------- .../traccar/notificators/NotificatorPushover.java | 50 +++++++-------------- .../traccar/notificators/NotificatorTelegram.java | 51 ++++++++-------------- .../traccar/notificators/NotificatorTraccar.java | 15 ++++--- .../org/traccar/notificators/NotificatorWeb.java | 20 ++++++--- 5 files changed, 72 insertions(+), 103 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index cafd2237d..3f1667568 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -17,24 +17,22 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.notification.NotificationMessage; import org.traccar.notification.NotificationFormatter; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; public class NotificatorFirebase implements Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorFirebase.class); + private final CacheManager cacheManager; + private final Client client; private final String url; private final String key; @@ -55,13 +53,16 @@ public class NotificatorFirebase implements Notificator { private Notification notification; } - public NotificatorFirebase() { + @Inject + public NotificatorFirebase(Config config, CacheManager cacheManager, Client client) { this( - "https://fcm.googleapis.com/fcm/send", - Context.getConfig().getString(Keys.NOTIFICATOR_FIREBASE_KEY)); + cacheManager, client, "https://fcm.googleapis.com/fcm/send", + config.getString(Keys.NOTIFICATOR_FIREBASE_KEY)); } - protected NotificatorFirebase(String url, String key) { + protected NotificatorFirebase(CacheManager cacheManager, Client client, String url, String key) { + this.cacheManager = cacheManager; + this.client = client; this.url = url; this.key = key; } @@ -70,8 +71,7 @@ public class NotificatorFirebase implements Notificator { public void send(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); @@ -82,18 +82,7 @@ public class NotificatorFirebase implements Notificator { message.tokens = user.getString("notificationTokens").split("[, ]"); message.notification = notification; - Context.getClient().target(url).request() - .header("Authorization", "key=" + key) - .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Firebase notification error", throwable); - } - }); + client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 70c1a6cdc..2ac489dd6 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -16,24 +16,22 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; public class NotificatorPushover implements Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorPushover.class); + private final CacheManager cacheManager; + private final Client client; private final String url; private final String token; @@ -52,33 +50,27 @@ public class NotificatorPushover implements Notificator { private String message; } - public NotificatorPushover() { + @Inject + public NotificatorPushover(Config config, CacheManager cacheManager, Client client) { + this.cacheManager = cacheManager; + this.client = client; url = "https://api.pushover.net/1/messages.json"; - token = Context.getConfig().getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); - user = Context.getConfig().getString(Keys.NOTIFICATOR_PUSHOVER_USER); + token = config.getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); + user = config.getString(Keys.NOTIFICATOR_PUSHOVER_USER); + if (token == null || user == null) { + throw new RuntimeException("Pushover token or user missing"); + } } @Override public void send(User user, Event event, Position position) { String device = ""; - if (user.getAttributes().containsKey("notificator.pushover.device")) { device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); } - if (token == null) { - LOGGER.warn("Pushover token not found"); - return; - } - - if (this.user == null) { - LOGGER.warn("Pushover user not found"); - return; - } - - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); Message message = new Message(); message.token = token; @@ -87,17 +79,7 @@ public class NotificatorPushover implements Notificator { message.title = shortMessage.getSubject(); message.message = shortMessage.getBody(); - Context.getClient().target(url).request() - .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Pushover API error", throwable); - } - }); + client.target(url).request().post(Entity.json(message)).close(); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 0ed53ac4c..1dccf2c04 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -17,24 +17,22 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.model.User; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; public class NotificatorTelegram implements Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorTelegram.class); + private final CacheManager cacheManager; + private final Client client; private final String urlSendText; private final String urlSendLocation; @@ -63,29 +61,16 @@ public class NotificatorTelegram implements Notificator { private int bearing; } - public NotificatorTelegram() { + @Inject + public NotificatorTelegram(Config config, CacheManager cacheManager, Client client) { + this.cacheManager = cacheManager; + this.client = client; urlSendText = String.format( - "https://api.telegram.org/bot%s/sendMessage", - Context.getConfig().getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); + "https://api.telegram.org/bot%s/sendMessage", config.getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); urlSendLocation = String.format( - "https://api.telegram.org/bot%s/sendLocation", - Context.getConfig().getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); - chatId = Context.getConfig().getString(Keys.NOTIFICATOR_TELEGRAM_CHAT_ID); - sendLocation = Context.getConfig().getBoolean(Keys.NOTIFICATOR_TELEGRAM_SEND_LOCATION); - } - - private void executeRequest(String url, Object message) { - Context.getClient().target(url).request() - .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Telegram API error", throwable); - } - }); + "https://api.telegram.org/bot%s/sendLocation", config.getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); + chatId = config.getString(Keys.NOTIFICATOR_TELEGRAM_CHAT_ID); + sendLocation = config.getBoolean(Keys.NOTIFICATOR_TELEGRAM_SEND_LOCATION); } private LocationMessage createLocationMessage(String messageChatId, Position position) { @@ -100,8 +85,7 @@ public class NotificatorTelegram implements Notificator { @Override public void send(User user, Event event, Position position) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); @@ -109,9 +93,10 @@ public class NotificatorTelegram implements Notificator { message.chatId = chatId; } message.text = shortMessage.getBody(); - executeRequest(urlSendText, message); + client.target(urlSendText).request().post(Entity.json(message)).close(); if (sendLocation && position != null) { - executeRequest(urlSendLocation, createLocationMessage(message.chatId, position)); + client.target(urlSendLocation).request().post( + Entity.json(createLocationMessage(message.chatId, position))).close(); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 5bcd18b5e..0827567ae 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 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. @@ -15,15 +15,20 @@ */ package org.traccar.notificators; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.session.cache.CacheManager; + +import javax.inject.Inject; +import javax.ws.rs.client.Client; public class NotificatorTraccar extends NotificatorFirebase { - public NotificatorTraccar() { + @Inject + public NotificatorTraccar(Config config, CacheManager cacheManager, Client client) { super( - "https://www.traccar.org/push/", - Context.getConfig().getString(Keys.NOTIFICATOR_TRACCAR_KEY)); + cacheManager, client, "https://www.traccar.org/push/", + config.getString(Keys.NOTIFICATOR_TRACCAR_KEY)); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index e19a94c1d..402f7a9f0 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -16,17 +16,26 @@ */ package org.traccar.notificators; -import org.traccar.Context; -import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; + public final class NotificatorWeb implements Notificator { + private final ConnectionManager connectionManager; + private final CacheManager cacheManager; + + @Inject + public NotificatorWeb(ConnectionManager connectionManager, CacheManager cacheManager) { + this.connectionManager = connectionManager; + this.cacheManager = cacheManager; + } + @Override public void send(User user, Event event, Position position) { @@ -40,11 +49,10 @@ public final class NotificatorWeb implements Notificator { copy.setMaintenanceId(event.getMaintenanceId()); copy.getAttributes().putAll(event.getAttributes()); - NotificationMessage message = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var message = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); copy.set("message", message.getBody()); - Context.getConnectionManager().updateEvent(user.getId(), copy); + connectionManager.updateEvent(user.getId(), copy); } } -- cgit v1.2.3 From 18fa5d9b7a234638183cd773dcb49987d51cc381 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 09:43:31 -0700 Subject: Special watch prefix --- src/main/java/org/traccar/protocol/WatchProtocolEncoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java index f1904ea4d..14ebe2852 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java @@ -67,6 +67,9 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin if (decoder != null) { hasIndex = decoder.getHasIndex(); manufacturer = decoder.getManufacturer(); + if (manufacturer.equals("3G")) { + manufacturer = "SG"; + } } } -- cgit v1.2.3 From 7d9eb1d2993ddc33523645ed4cce29729b0163ff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 18:08:40 -0700 Subject: GoSafe G1A additional data --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 6 +++++- src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 00093c978..b891bc388 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -123,7 +123,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { || BitUtil.check(value, 10) || BitUtil.check(value, 11)) { return Position.ALARM_FAULT; } - if (BitUtil.check(value, 7)) { + if (BitUtil.check(value, 7) || BitUtil.check(value, 18)) { return Position.ALARM_LOW_BATTERY; } if (BitUtil.check(value, 8)) { @@ -376,6 +376,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); position.set(Position.KEY_BLOCKED, BitUtil.check(status, 10)); + position.set(Position.KEY_CHARGE, BitUtil.check(status, 26)); position.setValid(BitUtil.check(status, 1)); @@ -540,6 +541,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x00CE: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); break; + case 0xE1: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; default: buf.skipBytes(extendedLength - 2); break; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 0b36b8f4d..49622745f 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "7e020000340551231425560568000000000400000201618a9706c320e100410000002722060816261501040000015d300115310105eb0a000300e164000300e301957e"), + Position.KEY_BATTERY_LEVEL, 100); + verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); -- cgit v1.2.3 From 8177c9b5ebd1a337fa97b93a31e8772f7b21c356 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 07:21:43 -0700 Subject: Remove object mapper usage --- .../org/traccar/protocol/StbProtocolDecoder.java | 33 +++++----------------- 1 file changed, 7 insertions(+), 26 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index c07337fc5..641359bfd 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.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. @@ -15,15 +15,12 @@ */ package org.traccar.protocol; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import javax.json.Json; import javax.json.JsonObject; @@ -42,29 +39,13 @@ public class StbProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_PROPERTY = 310; public static final int MSG_ALARM = 410; - public static class Response { - @JsonProperty("msgType") - private int type; - @JsonProperty("devId") - private String deviceId; - @JsonProperty("result") - private int result; - @JsonProperty("txnNo") - private String transaction; - } - private void sendResponse( - Channel channel, SocketAddress remoteAddress, int type, String deviceId, JsonObject root) - throws JsonProcessingException { - - Response response = new Response(); - response.type = type + 1; - response.deviceId = deviceId; - response.result = 1; - response.transaction = root.getString("txnNo"); + Channel channel, SocketAddress remoteAddress, int type, String deviceId, JsonObject root) { + String response = String.format( + "{ \"msgType\": %d, \"devId\": \"%s\", \"result\": 1, \"txnNo\": \"%s\" }", + type + 1, deviceId, root.getString("txnNo")); if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Context.getObjectMapper().writeValueAsString(response), remoteAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } -- cgit v1.2.3 From 5b269c0e309b70866ad167fb148eafcbad5a8b26 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 07:27:19 -0700 Subject: Inject event forwarder --- src/main/java/org/traccar/Context.java | 11 +---------- src/main/java/org/traccar/MainModule.java | 9 +++++++++ .../org/traccar/database/NotificationManager.java | 20 +++++++++----------- 3 files changed, 19 insertions(+), 21 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 471416926..95ff2eddb 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -127,12 +127,6 @@ public final class Context { return client; } - private static EventForwarder eventForwarder; - - public static EventForwarder getEventForwarder() { - return eventForwarder; - } - private static class ObjectMapperContextResolver implements ContextResolver { @Override @@ -181,10 +175,6 @@ public final class Context { initEventsModule(); - if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - eventForwarder = new EventForwarder(config); - } - } private static void initEventsModule() { @@ -192,6 +182,7 @@ public final class Context { notificationManager = new NotificationManager( dataManager, Main.getInjector().getInstance(CacheManager.class), + Main.getInjector().getInstance(EventForwarder.class), Main.getInjector().getInstance(NotificatorManager.class), Main.getInjector().getInstance(Geocoder.class)); Properties velocityProperties = new Properties(); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f6621a18e..e3f693444 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -25,6 +25,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.notification.EventForwarder; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -269,4 +270,12 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static EventForwarder provideEventForwarder(Config config) { + if (config.hasKey(Keys.EVENT_FORWARD_URL)) { + return new EventForwarder(config); + } + return null; + } + } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 1f4a48ac0..3c87aacb2 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 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"); @@ -37,6 +37,7 @@ import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; +import org.traccar.notification.EventForwarder; import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; @@ -49,16 +50,18 @@ public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); private final CacheManager cacheManager; + private final EventForwarder eventForwarder; private final NotificatorManager notificatorManager; private final Geocoder geocoder; private final boolean geocodeOnRequest; public NotificationManager( - DataManager dataManager, CacheManager cacheManager, + DataManager dataManager, CacheManager cacheManager, @Nullable EventForwarder eventForwarder, NotificatorManager notificatorManager, @Nullable Geocoder geocoder) { super(dataManager, Notification.class); this.cacheManager = cacheManager; + this.eventForwarder = eventForwarder; this.notificatorManager = notificatorManager; this.geocoder = geocoder; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); @@ -88,14 +91,9 @@ public class NotificationManager extends ExtendedObjectManager { long deviceId = event.getDeviceId(); Set users = Context.getPermissionsManager().getDeviceUsers(deviceId); - Set usersToForward = null; - if (Context.getEventForwarder() != null) { - usersToForward = new HashSet<>(); - } + Set usersToForward = new HashSet<>(); for (long userId : users) { - if (usersToForward != null) { - usersToForward.add(userId); - } + usersToForward.add(userId); final Set notificators = new HashSet<>(); for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { Notification notification = getById(notificationId); @@ -131,8 +129,8 @@ public class NotificationManager extends ExtendedObjectManager { } }).start(); } - if (Context.getEventForwarder() != null) { - Context.getEventForwarder().forwardEvent(event, position, usersToForward); + if (eventForwarder != null) { + eventForwarder.forwardEvent(event, position, usersToForward); } } -- cgit v1.2.3 From a401b40ee3b69d5679031a1e1d7287a0a56f4160 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 08:28:41 -0700 Subject: Inject velocity engine --- gradle/checkstyle.xml | 4 ++- src/main/java/org/traccar/Context.java | 30 ------------------ src/main/java/org/traccar/MainModule.java | 29 +++++++++++++++++ .../org/traccar/api/resource/PasswordResource.java | 13 ++++---- src/main/java/org/traccar/config/Keys.java | 17 ++++++++++ .../notification/NotificationFormatter.java | 20 ++++++++---- .../notification/TextTemplateFormatter.java | 23 ++++++++------ .../traccar/notificators/NotificatorFirebase.java | 14 ++++---- .../org/traccar/notificators/NotificatorMail.java | 11 +++---- .../traccar/notificators/NotificatorPushover.java | 9 +++--- .../org/traccar/notificators/NotificatorSms.java | 12 +++---- .../traccar/notificators/NotificatorTelegram.java | 9 +++--- .../traccar/notificators/NotificatorTraccar.java | 6 ++-- .../org/traccar/notificators/NotificatorWeb.java | 9 +++--- .../org/traccar/reports/common/ReportUtils.java | 8 +++-- .../java/org/traccar/reports/ReportUtilsTest.java | 37 +++++++++++----------- 16 files changed, 139 insertions(+), 112 deletions(-) (limited to 'src/main/java/org') diff --git a/gradle/checkstyle.xml b/gradle/checkstyle.xml index 6cff6ffa5..a6a6f0ff7 100644 --- a/gradle/checkstyle.xml +++ b/gradle/checkstyle.xml @@ -79,7 +79,9 @@ - + + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 95ff2eddb..627acd4e2 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -18,8 +18,6 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr353.JSR353Module; -import org.apache.velocity.app.VelocityEngine; -import org.eclipse.jetty.util.URIUtil; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -46,9 +44,6 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Properties; public final class Context { @@ -115,12 +110,6 @@ public final class Context { return notificationManager; } - private static VelocityEngine velocityEngine; - - public static VelocityEngine getVelocityEngine() { - return velocityEngine; - } - private static Client client = ClientBuilder.newClient(); public static Client getClient() { @@ -185,25 +174,6 @@ public final class Context { Main.getInjector().getInstance(EventForwarder.class), Main.getInjector().getInstance(NotificatorManager.class), Main.getInjector().getInstance(Geocoder.class)); - Properties velocityProperties = new Properties(); - velocityProperties.setProperty("file.resource.loader.path", - Context.getConfig().getString("templates.rootPath", "templates") + "/"); - velocityProperties.setProperty("runtime.log.logsystem.class", - "org.apache.velocity.runtime.log.NullLogChute"); - - String address; - try { - address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; - } - - String webUrl = URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); - webUrl = Context.getConfig().getString("web.url", webUrl); - velocityProperties.setProperty("web.url", webUrl); - - velocityEngine = new VelocityEngine(); - velocityEngine.init(velocityProperties); } public static BaseObjectManager getManager(Class clazz) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index e3f693444..a6f983a6b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -21,6 +21,9 @@ import com.google.inject.Provides; import com.google.inject.Scopes; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.log.NullLogChute; +import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -70,6 +73,9 @@ import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Properties; public class MainModule extends AbstractModule { @@ -278,4 +284,27 @@ public class MainModule extends AbstractModule { return null; } + @Singleton + @Provides + public static VelocityEngine provideVelocityEngine(Config config) { + Properties properties = new Properties(); + properties.setProperty("file.resource.loader.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); + properties.setProperty("runtime.log.logsystem.class", NullLogChute.class.getName()); + + String address; + try { + address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + + String url = config.getString( + Keys.WEB_URL, URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", "")); + properties.setProperty("web.url", url); + + VelocityEngine velocityEngine = new VelocityEngine(); + velocityEngine.init(properties); + return velocityEngine; + } + } diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 7df25c264..c7244f41c 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.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. @@ -15,12 +15,10 @@ */ package org.traccar.api.resource; -import org.apache.velocity.VelocityContext; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.model.User; -import org.traccar.notification.NotificationMessage; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; @@ -46,6 +44,9 @@ public class PasswordResource extends BaseResource { @Inject private MailManager mailManager; + @Inject + private TextTemplateFormatter textTemplateFormatter; + @Path("reset") @PermitAll @POST @@ -56,11 +57,9 @@ public class PasswordResource extends BaseResource { String token = UUID.randomUUID().toString().replaceAll("-", ""); user.set(PASSWORD_RESET_TOKEN, token); Context.getUsersManager().updateItem(user); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext( - permissionsService.getServer(), user); + var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); velocityContext.put("token", token); - NotificationMessage fullMessage = - TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); + var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); break; } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index d53245c65..82afe048b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -687,6 +687,14 @@ public final class Keys { "commands.queueing", Collections.singletonList(KeyType.GLOBAL)); + /** + * Root folder for all template files. + */ + public static final ConfigKey TEMPLATES_ROOT = new ConfigKey<>( + "templates.root", + Collections.singletonList(KeyType.GLOBAL), + "templates"); + /** * SMS API service full URL. Enables SMS commands and notifications. */ @@ -1245,6 +1253,15 @@ public final class Keys { "web.persistSession", Collections.singletonList(KeyType.GLOBAL)); + /** + * Public URL for the web app. Used for notification and report link. + * + * If not provided, Traccar will attempt to get a URL from the server IP address, but it might be a local address. + */ + public static final ConfigKey WEB_URL = new ConfigKey<>( + "web.url", + Collections.singletonList(KeyType.GLOBAL)); + /** * Output logging to the standard terminal output instead of a log file. */ diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 2d3b90412..fa244d9b4 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -27,18 +27,26 @@ import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.cache.CacheManager; -public final class NotificationFormatter { +import javax.inject.Inject; - private NotificationFormatter() { +public class NotificationFormatter { + + private final CacheManager cacheManager; + private final TextTemplateFormatter textTemplateFormatter; + + @Inject + public NotificationFormatter( + CacheManager cacheManager, TextTemplateFormatter textTemplateFormatter) { + this.cacheManager = cacheManager; + this.textTemplateFormatter = textTemplateFormatter; } - public static NotificationMessage formatMessage( - CacheManager cacheManager, User user, Event event, Position position, String templatePath) { + public NotificationMessage formatMessage(User user, Event event, Position position, String templatePath) { Server server = cacheManager.getServer(); Device device = cacheManager.getObject(Device.class, event.getDeviceId()); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(server, user); + VelocityContext velocityContext = textTemplateFormatter.prepareContext(server, user); velocityContext.put("device", device); velocityContext.put("event", event); @@ -59,7 +67,7 @@ public final class NotificationFormatter { velocityContext.put("driver", cacheManager.findDriverByUniqueId(device.getId(), driverUniqueId)); } - return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); + return textTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); } } diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 9072ec89e..bca18f53c 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -17,29 +17,34 @@ package org.traccar.notification; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.helper.model.UserUtil; import org.traccar.model.Server; import org.traccar.model.User; +import javax.inject.Inject; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.Locale; -public final class TextTemplateFormatter { +public class TextTemplateFormatter { private static final Logger LOGGER = LoggerFactory.getLogger(TextTemplateFormatter.class); - private TextTemplateFormatter() { + private final VelocityEngine velocityEngine; + + @Inject + public TextTemplateFormatter(VelocityEngine velocityEngine) { + this.velocityEngine = velocityEngine; } - public static VelocityContext prepareContext(Server server, User user) { + public VelocityContext prepareContext(Server server, User user) { VelocityContext velocityContext = new VelocityContext(); @@ -48,7 +53,7 @@ public final class TextTemplateFormatter { velocityContext.put("timezone", UserUtil.getTimezone(server, user)); } - velocityContext.put("webUrl", Context.getVelocityEngine().getProperty("web.url")); + velocityContext.put("webUrl", velocityEngine.getProperty("web.url")); velocityContext.put("dateTool", new DateTool()); velocityContext.put("numberTool", new NumberTool()); velocityContext.put("locale", Locale.getDefault()); @@ -56,23 +61,23 @@ public final class TextTemplateFormatter { return velocityContext; } - public static Template getTemplate(String name, String path) { + public Template getTemplate(String name, String path) { String templateFilePath; Template template; try { templateFilePath = Paths.get(path, name + ".vm").toString(); - template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); + template = velocityEngine.getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); } catch (ResourceNotFoundException error) { LOGGER.warn("Notification template error", error); templateFilePath = Paths.get(path, "unknown.vm").toString(); - template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); + template = velocityEngine.getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); } return template; } - public static NotificationMessage formatMessage(VelocityContext velocityContext, String name, String templatePath) { + public NotificationMessage formatMessage(VelocityContext velocityContext, String name, String templatePath) { StringWriter writer = new StringWriter(); getTemplate(name, templatePath).merge(velocityContext, writer); return new NotificationMessage((String) velocityContext.get("subject"), writer.toString()); diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 3f1667568..5787b7ef2 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -23,7 +23,6 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -31,7 +30,7 @@ import javax.ws.rs.client.Entity; public class NotificatorFirebase implements Notificator { - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final Client client; private final String url; @@ -54,14 +53,15 @@ public class NotificatorFirebase implements Notificator { } @Inject - public NotificatorFirebase(Config config, CacheManager cacheManager, Client client) { + public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter, Client client) { this( - cacheManager, client, "https://fcm.googleapis.com/fcm/send", + notificationFormatter, client, "https://fcm.googleapis.com/fcm/send", config.getString(Keys.NOTIFICATOR_FIREBASE_KEY)); } - protected NotificatorFirebase(CacheManager cacheManager, Client client, String url, String key) { - this.cacheManager = cacheManager; + protected NotificatorFirebase( + NotificationFormatter notificationFormatter, Client client, String url, String key) { + this.notificationFormatter = notificationFormatter; this.client = client; this.url = url; this.key = key; @@ -71,7 +71,7 @@ public class NotificatorFirebase implements Notificator { public void send(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { - var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index fe8d69af2..647832166 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -20,10 +20,8 @@ import org.traccar.database.MailManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.notification.NotificationMessage; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.mail.MessagingException; @@ -31,19 +29,18 @@ import javax.mail.MessagingException; public class NotificatorMail implements Notificator { private final MailManager mailManager; - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; @Inject - public NotificatorMail(MailManager mailManager, CacheManager cacheManager) { + public NotificatorMail(MailManager mailManager, NotificationFormatter notificationFormatter) { this.mailManager = mailManager; - this.cacheManager = cacheManager; + this.notificationFormatter = notificationFormatter; } @Override public void send(User user, Event event, Position position) throws MessageException { try { - NotificationMessage fullMessage = NotificationFormatter.formatMessage( - cacheManager, user, event, position, "full"); + var fullMessage = notificationFormatter.formatMessage(user, event, position, "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 2ac489dd6..32ceae780 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -22,7 +22,6 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -30,7 +29,7 @@ import javax.ws.rs.client.Entity; public class NotificatorPushover implements Notificator { - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final Client client; private final String url; @@ -51,8 +50,8 @@ public class NotificatorPushover implements Notificator { } @Inject - public NotificatorPushover(Config config, CacheManager cacheManager, Client client) { - this.cacheManager = cacheManager; + public NotificatorPushover(Config config, NotificationFormatter notificationFormatter, Client client) { + this.notificationFormatter = notificationFormatter; this.client = client; url = "https://api.pushover.net/1/messages.json"; token = config.getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); @@ -70,7 +69,7 @@ public class NotificatorPushover implements Notificator { device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); } - var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); Message message = new Message(); message.token = token; diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index f4d1de0cb..544b67a5e 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -22,8 +22,6 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; -import org.traccar.session.cache.CacheManager; import org.traccar.sms.SmsManager; import javax.inject.Inject; @@ -31,21 +29,21 @@ import javax.inject.Inject; public class NotificatorSms implements Notificator { private final SmsManager smsManager; - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final StatisticsManager statisticsManager; @Inject - public NotificatorSms(SmsManager smsManager, CacheManager cacheManager, StatisticsManager statisticsManager) { + public NotificatorSms( + SmsManager smsManager, NotificationFormatter notificationFormatter, StatisticsManager statisticsManager) { this.smsManager = smsManager; - this.cacheManager = cacheManager; + this.notificationFormatter = notificationFormatter; this.statisticsManager = statisticsManager; } @Override public void send(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); statisticsManager.registerSms(); smsManager.sendMessage(user.getPhone(), shortMessage.getBody(), false); } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 1dccf2c04..a00cd36f1 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -23,7 +23,6 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -31,7 +30,7 @@ import javax.ws.rs.client.Entity; public class NotificatorTelegram implements Notificator { - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final Client client; private final String urlSendText; @@ -62,8 +61,8 @@ public class NotificatorTelegram implements Notificator { } @Inject - public NotificatorTelegram(Config config, CacheManager cacheManager, Client client) { - this.cacheManager = cacheManager; + public NotificatorTelegram(Config config, NotificationFormatter notificationFormatter, Client client) { + this.notificationFormatter = notificationFormatter; this.client = client; urlSendText = String.format( "https://api.telegram.org/bot%s/sendMessage", config.getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); @@ -85,7 +84,7 @@ public class NotificatorTelegram implements Notificator { @Override public void send(User user, Event event, Position position) { - var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 0827567ae..8f1260e96 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -17,7 +17,7 @@ package org.traccar.notificators; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.session.cache.CacheManager; +import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -25,9 +25,9 @@ import javax.ws.rs.client.Client; public class NotificatorTraccar extends NotificatorFirebase { @Inject - public NotificatorTraccar(Config config, CacheManager cacheManager, Client client) { + public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { super( - cacheManager, client, "https://www.traccar.org/push/", + notificationFormatter, client, "https://www.traccar.org/push/", config.getString(Keys.NOTIFICATOR_TRACCAR_KEY)); } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 402f7a9f0..3d899584d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -21,19 +21,18 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import org.traccar.session.ConnectionManager; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; public final class NotificatorWeb implements Notificator { private final ConnectionManager connectionManager; - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; @Inject - public NotificatorWeb(ConnectionManager connectionManager, CacheManager cacheManager) { + public NotificatorWeb(ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { this.connectionManager = connectionManager; - this.cacheManager = cacheManager; + this.notificationFormatter = notificationFormatter; } @Override @@ -49,7 +48,7 @@ public final class NotificatorWeb implements Notificator { copy.setMaintenanceId(event.getMaintenanceId()); copy.getAttributes().putAll(event.getAttributes()); - var message = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var message = notificationFormatter.formatMessage(user, event, position, "short"); copy.set("message", message.getBody()); connectionManager.updateEvent(user.getId(), copy); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 706475241..95c43f8a0 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -16,6 +16,7 @@ */ package org.traccar.reports.common; +import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.NumberTool; import org.jxls.area.Area; @@ -74,18 +75,21 @@ public class ReportUtils { private final IdentityManager identityManager; private final DeviceManager deviceManager; private final TripsConfig tripsConfig; + private final VelocityEngine velocityEngine; private final Geocoder geocoder; @Inject public ReportUtils( Config config, Storage storage, PermissionsService permissionsService, IdentityManager identityManager, - DeviceManager deviceManager, TripsConfig tripsConfig, @Nullable Geocoder geocoder) { + DeviceManager deviceManager, TripsConfig tripsConfig, VelocityEngine velocityEngine, + @Nullable Geocoder geocoder) { this.config = config; this.storage = storage; this.permissionsService = permissionsService; this.identityManager = identityManager; this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; + this.velocityEngine = velocityEngine; this.geocoder = geocoder; } @@ -153,7 +157,7 @@ public class ReportUtils { context.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); context.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); context.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); - context.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); + context.putVar("webUrl", velocityEngine.getProperty("web.url")); context.putVar("dateTool", new DateTool()); context.putVar("numberTool", new NumberTool()); context.putVar("timezone", UserUtil.getTimezone(server, user)); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 92bfdae1c..1440c4c30 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -1,5 +1,6 @@ package org.traccar.reports; +import org.apache.velocity.app.VelocityEngine; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; @@ -76,8 +77,8 @@ public class ReportUtilsTest extends BaseTest { @Test public void testCalculateSpentFuel() { ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), mock(TripsConfig.class), null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), mock(TripsConfig.class), mock(VelocityEngine.class), null); Position startPosition = new Position(); Position endPosition = new Position(); assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); @@ -101,8 +102,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -156,8 +157,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -227,8 +228,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -278,8 +279,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -307,8 +308,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -336,8 +337,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -365,8 +366,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -390,8 +391,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); -- cgit v1.2.3 From aa00ed23f96f91cfc879f02e61333511e3b7b11b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 14:11:01 -0700 Subject: Remove JSR353 support --- build.gradle | 1 - src/main/java/org/traccar/Context.java | 2 -- 2 files changed, 3 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 8c196043a..46227d1ff 100644 --- a/build.gradle +++ b/build.gradle @@ -63,7 +63,6 @@ dependencies { implementation "org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion" implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" - implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" implementation "org.liquibase:liquibase-core:4.7.0" implementation "com.sun.mail:javax.mail:1.6.2" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 627acd4e2..68a711878 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -17,7 +17,6 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -140,7 +139,6 @@ public final class Context { if (config.getBoolean(Keys.WEB_SANITIZE)) { objectMapper.registerModule(new SanitizerModule()); } - objectMapper.registerModule(new JSR353Module()); objectMapper.setConfig( objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); -- cgit v1.2.3 From 4025a42c42e34bb620f4263de05781a10ddc7a9d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 14:27:01 -0700 Subject: Inject object mapper --- src/main/java/org/traccar/Context.java | 17 +---------------- src/main/java/org/traccar/MainModule.java | 17 +++++++++++++---- src/main/java/org/traccar/api/AsyncSocket.java | 9 ++++++--- .../java/org/traccar/api/AsyncSocketServlet.java | 13 +++++++++++-- .../java/org/traccar/api/ObjectMapperProvider.java | 4 ++-- .../java/org/traccar/database/DataManager.java | 3 ++- .../java/org/traccar/storage/DatabaseStorage.java | 19 +++++++++++-------- .../java/org/traccar/storage/QueryBuilder.java | 22 +++++++++++++++------- src/main/java/org/traccar/web/WebServer.java | 7 +++++-- 9 files changed, 66 insertions(+), 45 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 68a711878..54bb2af4b 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -16,7 +16,6 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -29,7 +28,6 @@ import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; -import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; @@ -55,12 +53,6 @@ public final class Context { return config; } - private static ObjectMapper objectMapper; - - public static ObjectMapper getObjectMapper() { - return objectMapper; - } - private static IdentityManager identityManager; public static IdentityManager getIdentityManager() { @@ -119,7 +111,7 @@ public final class Context { @Override public ObjectMapper getContext(Class clazz) { - return objectMapper; + return Main.getInjector().getInstance(ObjectMapper.class); } } @@ -135,13 +127,6 @@ public final class Context { throw e; } - objectMapper = new ObjectMapper(); - if (config.getBoolean(Keys.WEB_SANITIZE)) { - objectMapper.registerModule(new SanitizerModule()); - } - objectMapper.setConfig( - objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); if (config.hasKey(Keys.DATABASE_URL)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a6f983a6b..794735daf 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -16,7 +16,9 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.google.inject.AbstractModule; +import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; import io.netty.util.HashedWheelTimer; @@ -28,6 +30,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; @@ -85,8 +88,14 @@ public class MainModule extends AbstractModule { } @Provides - public static ObjectMapper provideObjectMapper() { - return Context.getObjectMapper(); + public static ObjectMapper provideObjectMapper(Config config) { + ObjectMapper objectMapper = new ObjectMapper(); + if (config.getBoolean(Keys.WEB_SANITIZE)) { + objectMapper.registerModule(new SanitizerModule()); + } + objectMapper.setConfig(objectMapper + .getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); + return objectMapper; } @Provides @@ -145,9 +154,9 @@ public class MainModule extends AbstractModule { } @Provides - public static WebServer provideWebServer(Config config) { + public static WebServer provideWebServer(Injector injector, Config config) { if (config.hasKey(Keys.WEB_PORT)) { - return new WebServer(config); + return new WebServer(injector, config); } return null; } diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index b5902c4fb..2b866176b 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 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. @@ -16,6 +16,7 @@ package org.traccar.api; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.slf4j.Logger; @@ -39,9 +40,11 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private static final String KEY_POSITIONS = "positions"; private static final String KEY_EVENTS = "events"; + private final ObjectMapper objectMapper; private final long userId; - public AsyncSocket(long userId) { + public AsyncSocket(ObjectMapper objectMapper, long userId) { + this.objectMapper = objectMapper; this.userId = userId; } @@ -92,7 +95,7 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private void sendData(Map> data) { if (isConnected()) { try { - getRemote().sendString(Context.getObjectMapper().writeValueAsString(data), null); + getRemote().sendString(objectMapper.writeValueAsString(data), null); } catch (JsonProcessingException e) { LOGGER.warn("Socket JSON formatting error", e); } diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index a964ead10..4e55dfebf 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 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. @@ -15,24 +15,33 @@ */ package org.traccar.api; +import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.traccar.Context; import org.traccar.api.resource.SessionResource; import org.traccar.config.Keys; +import javax.inject.Inject; import javax.servlet.http.HttpSession; import java.time.Duration; public class AsyncSocketServlet extends JettyWebSocketServlet { + private final ObjectMapper objectMapper; + + @Inject + public AsyncSocketServlet(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @Override public void configure(JettyWebSocketServletFactory factory) { factory.setIdleTimeout(Duration.ofMillis(Context.getConfig().getLong(Keys.WEB_TIMEOUT))); factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(userId); + return new AsyncSocket(objectMapper, userId); } else { return null; } diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java index f81b20917..cb7adab6c 100644 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -16,7 +16,7 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; -import org.traccar.Context; +import org.traccar.Main; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; @@ -26,7 +26,7 @@ public class ObjectMapperProvider implements ContextResolver { @Override public ObjectMapper getContext(Class type) { - return Context.getObjectMapper(); + return Main.getInjector().getInstance(ObjectMapper.class); } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 29d70ec32..556f1e348 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -15,6 +15,7 @@ */ package org.traccar.database; +import com.fasterxml.jackson.databind.ObjectMapper; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import liquibase.Contexts; @@ -78,7 +79,7 @@ public class DataManager { initDatabase(); initDatabaseSchema(); - storage = new DatabaseStorage(dataSource); + storage = new DatabaseStorage(dataSource, Main.getInjector().getInstance(ObjectMapper.class)); } private void initDatabase() throws Exception { diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index fc468182e..661e792d4 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import com.fasterxml.jackson.databind.ObjectMapper; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; @@ -38,9 +39,11 @@ import java.util.stream.Collectors; public class DatabaseStorage extends Storage { private final DataSource dataSource; + private final ObjectMapper objectMapper; - public DatabaseStorage(DataSource dataSource) { + public DatabaseStorage(DataSource dataSource, ObjectMapper objectMapper) { this.dataSource = dataSource; + this.objectMapper = objectMapper; } @Override @@ -52,7 +55,7 @@ public class DatabaseStorage extends Storage { query.append(formatOrder(request.getOrder())); query.append(formatLimit(request.getLimit())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -72,7 +75,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> ':' + c)); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); builder.setObject(entity); return builder.executeUpdate(); } catch (SQLException e) { @@ -88,7 +91,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); builder.setObject(entity); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); @@ -105,7 +108,7 @@ public class DatabaseStorage extends Storage { query.append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -133,7 +136,7 @@ public class DatabaseStorage extends Storage { Condition combinedCondition = Condition.merge(conditions); query.append(formatCondition(combinedCondition)); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(combinedCondition).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -151,7 +154,7 @@ public class DatabaseStorage extends Storage { query.append(permission.get().keySet().stream().map(key -> ':' + key).collect(Collectors.joining(", "))); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } @@ -169,7 +172,7 @@ public class DatabaseStorage extends Storage { query.append(permission .get().keySet().stream().map(key -> key + " = :" + key).collect(Collectors.joining(" AND "))); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 874a046b4..8502d5f0b 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -16,6 +16,7 @@ package org.traccar.storage; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; @@ -45,13 +46,18 @@ public final class QueryBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class); + private final ObjectMapper objectMapper; + private final Map> indexMap = new HashMap<>(); private Connection connection; private PreparedStatement statement; private final String query; private final boolean returnGeneratedKeys; - private QueryBuilder(DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { + private QueryBuilder( + DataSource dataSource, ObjectMapper objectMapper, + String query, boolean returnGeneratedKeys) throws SQLException { + this.objectMapper = objectMapper; this.query = query; this.returnGeneratedKeys = returnGeneratedKeys; if (query != null) { @@ -126,13 +132,15 @@ public final class QueryBuilder { return parsedQuery.toString(); } - public static QueryBuilder create(DataSource dataSource, String query) throws SQLException { - return new QueryBuilder(dataSource, query, false); + public static QueryBuilder create( + DataSource dataSource, ObjectMapper objectMapper, String query) throws SQLException { + return new QueryBuilder(dataSource, objectMapper, query, false); } public static QueryBuilder create( - DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { - return new QueryBuilder(dataSource, query, returnGeneratedKeys); + DataSource dataSource, ObjectMapper objectMapper, String query, + boolean returnGeneratedKeys) throws SQLException { + return new QueryBuilder(dataSource, objectMapper, query, returnGeneratedKeys); } private List indexes(String name) { @@ -295,7 +303,7 @@ public final class QueryBuilder { } else if (method.getReturnType().equals(byte[].class)) { setBlob(name, (byte[]) method.invoke(object)); } else { - setString(name, Context.getObjectMapper().writeValueAsString(method.invoke(object))); + setString(name, objectMapper.writeValueAsString(method.invoke(object))); } } catch (IllegalAccessException | InvocationTargetException | JsonProcessingException error) { LOGGER.warn("Get property error", error); @@ -378,7 +386,7 @@ public final class QueryBuilder { String value = resultSet.getString(name); if (value != null && !value.isEmpty()) { try { - method.invoke(object, Context.getObjectMapper().readValue(value, parameterType)); + method.invoke(object, objectMapper.readValue(value, parameterType)); } catch (InvocationTargetException | IllegalAccessException | IOException error) { LOGGER.warn("Set property error", error); } diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index fdbfc1464..933e8c845 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,6 +15,7 @@ */ package org.traccar.web; +import com.google.inject.Injector; import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.http.HttpMethod; @@ -78,10 +79,12 @@ public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); + private final Injector injector; private final Server server; @Inject - public WebServer(Config config) { + public WebServer(Injector injector, Config config) { + this.injector = injector; String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); if (address == null) { @@ -169,7 +172,7 @@ public class WebServer implements LifecycleObject { private void initApi(Config config, ServletContextHandler servletHandler) { servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); - servletHandler.addServlet(new ServletHolder(new AsyncSocketServlet()), "/api/socket"); + servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); JettyWebSocketServletContainerInitializer.configure(servletHandler, null); String mediaPath = config.getString(Keys.MEDIA_PATH); -- cgit v1.2.3 From 7c08991f12b4958135fdffc26f272677c03630ad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 15:04:51 -0700 Subject: Inject network client --- src/main/java/org/traccar/Context.java | 22 ------- src/main/java/org/traccar/MainModule.java | 68 ++++++++++++---------- .../java/org/traccar/geocoder/BanGeocoder.java | 5 +- .../org/traccar/geocoder/BingMapsGeocoder.java | 5 +- .../java/org/traccar/geocoder/FactualGeocoder.java | 5 +- .../org/traccar/geocoder/GeoapifyGeocoder.java | 5 +- .../org/traccar/geocoder/GeocodeFarmGeocoder.java | 6 +- .../org/traccar/geocoder/GeocodeXyzGeocoder.java | 5 +- .../org/traccar/geocoder/GisgraphyGeocoder.java | 5 +- .../java/org/traccar/geocoder/GoogleGeocoder.java | 5 +- .../java/org/traccar/geocoder/HereGeocoder.java | 6 +- .../java/org/traccar/geocoder/JsonGeocoder.java | 9 +-- .../org/traccar/geocoder/MapQuestGeocoder.java | 5 +- .../org/traccar/geocoder/MapTilerGeocoder.java | 5 +- .../java/org/traccar/geocoder/MapboxGeocoder.java | 5 +- .../org/traccar/geocoder/MapmyIndiaGeocoder.java | 5 +- .../org/traccar/geocoder/NominatimGeocoder.java | 6 +- .../org/traccar/geocoder/OpenCageGeocoder.java | 6 +- .../traccar/geocoder/PositionStackGeocoder.java | 5 +- .../java/org/traccar/geocoder/TomTomGeocoder.java | 5 +- .../geolocation/GoogleGeolocationProvider.java | 8 ++- .../geolocation/MozillaGeolocationProvider.java | 8 ++- .../geolocation/OpenCellIdGeolocationProvider.java | 12 ++-- .../geolocation/UniversalGeolocationProvider.java | 12 ++-- .../geolocation/UnwiredGeolocationProvider.java | 16 ++--- .../org/traccar/notification/EventForwarder.java | 16 +++-- .../java/org/traccar/schedule/ScheduleManager.java | 15 +++-- .../java/org/traccar/schedule/ScheduleTask.java | 22 +++++++ .../schedule/TaskDeviceInactivityCheck.java | 22 +++++-- .../java/org/traccar/schedule/TaskHealthCheck.java | 23 +++++--- .../traccar/schedule/TaskWebSocketKeepalive.java | 17 ++++-- src/main/java/org/traccar/sms/HttpSmsClient.java | 23 ++++---- src/main/java/org/traccar/sms/SnsSmsClient.java | 24 +++----- .../speedlimit/OverpassSpeedLimitProvider.java | 10 ++-- .../java/org/traccar/geocoder/GeocoderTest.java | 30 +++++----- .../geolocation/GeolocationProviderTest.java | 11 +++- .../speedlimit/OverpassSpeedLimitProviderTest.java | 11 +++- 37 files changed, 279 insertions(+), 189 deletions(-) create mode 100644 src/main/java/org/traccar/schedule/ScheduleTask.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 54bb2af4b..62ad01c24 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -15,7 +15,6 @@ */ package org.traccar; -import com.fasterxml.jackson.databind.ObjectMapper; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -38,10 +37,6 @@ import org.traccar.notification.NotificatorManager; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.ext.ContextResolver; - public final class Context { private Context() { @@ -101,21 +96,6 @@ public final class Context { return notificationManager; } - private static Client client = ClientBuilder.newClient(); - - public static Client getClient() { - return client; - } - - private static class ObjectMapperContextResolver implements ContextResolver { - - @Override - public ObjectMapper getContext(Class clazz) { - return Main.getInjector().getInstance(ObjectMapper.class); - } - - } - public static void init(String configFile) throws Exception { try { @@ -127,8 +107,6 @@ public final class Context { throw e; } - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); - if (config.hasKey(Keys.DATABASE_URL)) { dataManager = new DataManager(config); } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 794735daf..2c88dbc13 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,6 +30,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.ConnectionManager; @@ -64,6 +65,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -75,6 +77,8 @@ import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.ext.ContextResolver; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -125,7 +129,8 @@ public class MainModule extends AbstractModule { @Provides public static Client provideClient() { - return Context.getClient(); + return ClientBuilder.newClient().register( + (ContextResolver) clazz -> Main.getInjector().getInstance(ObjectMapper.class)); } @Provides @@ -135,11 +140,11 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static SmsManager provideSmsManager(Config config) { + public static SmsManager provideSmsManager(Config config, Client client) { if (config.hasKey(Keys.SMS_HTTP_URL)) { - return new HttpSmsClient(); + return new HttpSmsClient(config, client); } else if (config.hasKey(Keys.SMS_AWS_REGION)) { - return new SnsSmsClient(); + return new SnsSmsClient(config); } return null; } @@ -163,7 +168,7 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static Geocoder provideGeocoder(Config config) { + public static Geocoder provideGeocoder(Config config, Client client) { if (config.getBoolean(Keys.GEOCODER_ENABLE)) { String type = config.getString(Keys.GEOCODER_TYPE, "google"); String url = config.getString(Keys.GEOCODER_URL); @@ -176,39 +181,39 @@ public class MainModule extends AbstractModule { int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); switch (type) { case "nominatim": - return new NominatimGeocoder(url, key, language, cacheSize, addressFormat); + return new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); case "gisgraphy": - return new GisgraphyGeocoder(url, cacheSize, addressFormat); + return new GisgraphyGeocoder(client, url, cacheSize, addressFormat); case "mapquest": - return new MapQuestGeocoder(url, key, cacheSize, addressFormat); + return new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); case "opencage": - return new OpenCageGeocoder(url, key, language, cacheSize, addressFormat); + return new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); case "bingmaps": - return new BingMapsGeocoder(url, key, cacheSize, addressFormat); + return new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); case "factual": - return new FactualGeocoder(url, key, cacheSize, addressFormat); + return new FactualGeocoder(client, url, key, cacheSize, addressFormat); case "geocodefarm": - return new GeocodeFarmGeocoder(key, language, cacheSize, addressFormat); + return new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); case "geocodexyz": - return new GeocodeXyzGeocoder(key, cacheSize, addressFormat); + return new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); case "ban": - return new BanGeocoder(cacheSize, addressFormat); + return new BanGeocoder(client, cacheSize, addressFormat); case "here": - return new HereGeocoder(url, id, key, language, cacheSize, addressFormat); + return new HereGeocoder(client, url, id, key, language, cacheSize, addressFormat); case "mapmyindia": - return new MapmyIndiaGeocoder(url, key, cacheSize, addressFormat); + return new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); case "tomtom": - return new TomTomGeocoder(url, key, cacheSize, addressFormat); + return new TomTomGeocoder(client, url, key, cacheSize, addressFormat); case "positionstack": - return new PositionStackGeocoder(key, cacheSize, addressFormat); + return new PositionStackGeocoder(client, key, cacheSize, addressFormat); case "mapbox": - return new MapboxGeocoder(key, cacheSize, addressFormat); + return new MapboxGeocoder(client, key, cacheSize, addressFormat); case "maptiler": - return new MapTilerGeocoder(key, cacheSize, addressFormat); + return new MapTilerGeocoder(client, key, cacheSize, addressFormat); case "geoapify": - return new GeoapifyGeocoder(key, language, cacheSize, addressFormat); + return new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); default: - return new GoogleGeocoder(key, language, cacheSize, addressFormat); + return new GoogleGeocoder(client, key, language, cacheSize, addressFormat); } } return null; @@ -216,20 +221,20 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static GeolocationProvider provideGeolocationProvider(Config config) { + public static GeolocationProvider provideGeolocationProvider(Config config, Client client) { if (config.getBoolean(Keys.GEOLOCATION_ENABLE)) { String type = config.getString(Keys.GEOLOCATION_TYPE, "mozilla"); String url = config.getString(Keys.GEOLOCATION_URL); String key = config.getString(Keys.GEOLOCATION_KEY); switch (type) { case "google": - return new GoogleGeolocationProvider(key); + return new GoogleGeolocationProvider(client, key); case "opencellid": - return new OpenCellIdGeolocationProvider(url, key); + return new OpenCellIdGeolocationProvider(client, url, key); case "unwired": - return new UnwiredGeolocationProvider(url, key); + return new UnwiredGeolocationProvider(client, url, key); default: - return new MozillaGeolocationProvider(key); + return new MozillaGeolocationProvider(client, key); } } return null; @@ -237,14 +242,14 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static SpeedLimitProvider provideSpeedLimitProvider(Config config) { + public static SpeedLimitProvider provideSpeedLimitProvider(Config config, Client client) { if (config.getBoolean(Keys.SPEED_LIMIT_ENABLE)) { String type = config.getString(Keys.SPEED_LIMIT_TYPE, "overpass"); String url = config.getString(Keys.SPEED_LIMIT_URL); switch (type) { case "overpass": default: - return new OverpassSpeedLimitProvider(url); + return new OverpassSpeedLimitProvider(client, url); } } return null; @@ -286,9 +291,10 @@ public class MainModule extends AbstractModule { } @Provides - public static EventForwarder provideEventForwarder(Config config) { + public static EventForwarder provideEventForwarder( + Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarder(config); + return new EventForwarder(config, client, cacheManager, usersManager); } return null; } diff --git a/src/main/java/org/traccar/geocoder/BanGeocoder.java b/src/main/java/org/traccar/geocoder/BanGeocoder.java index b1f0900a4..f878a8bab 100644 --- a/src/main/java/org/traccar/geocoder/BanGeocoder.java +++ b/src/main/java/org/traccar/geocoder/BanGeocoder.java @@ -22,11 +22,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class BanGeocoder extends JsonGeocoder { - public BanGeocoder(int cacheSize, AddressFormat addressFormat) { - super("https://api-adresse.data.gouv.fr/reverse/?lat=%f&lon=%f", cacheSize, addressFormat); + public BanGeocoder(Client client, int cacheSize, AddressFormat addressFormat) { + super(client, "https://api-adresse.data.gouv.fr/reverse/?lat=%f&lon=%f", cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java b/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java index 32a26ee0c..01e33c2ea 100644 --- a/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java +++ b/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java @@ -18,11 +18,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class BingMapsGeocoder extends JsonGeocoder { - public BingMapsGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "/Locations/%f,%f?key=" + key + "&include=ciso2", cacheSize, addressFormat); + public BingMapsGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, url + "/Locations/%f,%f?key=" + key + "&include=ciso2", cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/FactualGeocoder.java b/src/main/java/org/traccar/geocoder/FactualGeocoder.java index f540eb8fe..384f46b0e 100644 --- a/src/main/java/org/traccar/geocoder/FactualGeocoder.java +++ b/src/main/java/org/traccar/geocoder/FactualGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class FactualGeocoder extends JsonGeocoder { @@ -28,8 +29,8 @@ public class FactualGeocoder extends JsonGeocoder { return url; } - public FactualGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key), cacheSize, addressFormat); + public FactualGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java index ef0e4c8bd..4748d6a2c 100644 --- a/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GeoapifyGeocoder extends JsonGeocoder { @@ -31,8 +32,8 @@ public class GeoapifyGeocoder extends JsonGeocoder { return url; } - public GeoapifyGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); + public GeoapifyGeocoder(Client client, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java b/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java index 39a3300a0..2af95910f 100644 --- a/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GeocodeFarmGeocoder extends JsonGeocoder { @@ -30,8 +31,9 @@ public class GeocodeFarmGeocoder extends JsonGeocoder { } return url; } - public GeocodeFarmGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); + public GeocodeFarmGeocoder( + Client client, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java b/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java index aca360c3d..96491ece3 100644 --- a/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GeocodeXyzGeocoder extends JsonGeocoder { @@ -27,8 +28,8 @@ public class GeocodeXyzGeocoder extends JsonGeocoder { return url; } - public GeocodeXyzGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key), cacheSize, addressFormat); + public GeocodeXyzGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java b/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java index b4881a006..0589eb000 100644 --- a/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GisgraphyGeocoder extends JsonGeocoder { @@ -27,8 +28,8 @@ public class GisgraphyGeocoder extends JsonGeocoder { return url; } - public GisgraphyGeocoder(String url, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url), cacheSize, addressFormat); + public GisgraphyGeocoder(Client client, String url, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java index 9494cab45..4d9ec8f36 100644 --- a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonString; +import javax.ws.rs.client.Client; public class GoogleGeocoder extends JsonGeocoder { @@ -32,8 +33,8 @@ public class GoogleGeocoder extends JsonGeocoder { return url; } - public GoogleGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); + public GoogleGeocoder(Client client, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/HereGeocoder.java b/src/main/java/org/traccar/geocoder/HereGeocoder.java index 40390e65b..eb639995e 100644 --- a/src/main/java/org/traccar/geocoder/HereGeocoder.java +++ b/src/main/java/org/traccar/geocoder/HereGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class HereGeocoder extends JsonGeocoder { @@ -35,8 +36,9 @@ public class HereGeocoder extends JsonGeocoder { } public HereGeocoder( - String url, String id, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, id, key, language), cacheSize, addressFormat); + Client client, String url, String id, String key, String language, + int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, id, key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/JsonGeocoder.java b/src/main/java/org/traccar/geocoder/JsonGeocoder.java index f20aa79d6..0262de18c 100644 --- a/src/main/java/org/traccar/geocoder/JsonGeocoder.java +++ b/src/main/java/org/traccar/geocoder/JsonGeocoder.java @@ -17,13 +17,12 @@ package org.traccar.geocoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; import org.traccar.database.StatisticsManager; import javax.json.JsonObject; import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.Client; import javax.ws.rs.client.InvocationCallback; import java.util.AbstractMap; import java.util.Collections; @@ -34,12 +33,14 @@ public abstract class JsonGeocoder implements Geocoder { private static final Logger LOGGER = LoggerFactory.getLogger(JsonGeocoder.class); + private final Client client; private final String url; private final AddressFormat addressFormat; private Map, String> cache; - public JsonGeocoder(String url, final int cacheSize, AddressFormat addressFormat) { + public JsonGeocoder(Client client, String url, final int cacheSize, AddressFormat addressFormat) { + this.client = client; this.url = url; this.addressFormat = addressFormat; if (cacheSize > 0) { @@ -101,7 +102,7 @@ public abstract class JsonGeocoder implements Geocoder { Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); } - Invocation.Builder request = Context.getClient().target(String.format(url, latitude, longitude)).request(); + var request = client.target(String.format(url, latitude, longitude)).request(); if (callback != null) { request.async().get(new InvocationCallback() { diff --git a/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java b/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java index 8dc3f76f0..3f2554c6e 100644 --- a/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class MapQuestGeocoder extends JsonGeocoder { @@ -29,8 +30,8 @@ public class MapQuestGeocoder extends JsonGeocoder { return url; } - public MapQuestGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key), cacheSize, addressFormat); + public MapQuestGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java index 6b688a6e8..203f5f99b 100644 --- a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java @@ -17,11 +17,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class MapTilerGeocoder extends JsonGeocoder { - public MapTilerGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super("https://api.maptiler.com/geocoding/%2$f,%1$f.json?key=" + key, cacheSize, addressFormat); + public MapTilerGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, "https://api.maptiler.com/geocoding/%2$f,%1$f.json?key=" + key, cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/MapboxGeocoder.java b/src/main/java/org/traccar/geocoder/MapboxGeocoder.java index 9b987c9d8..72bfb53f5 100644 --- a/src/main/java/org/traccar/geocoder/MapboxGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapboxGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonString; +import javax.ws.rs.client.Client; public class MapboxGeocoder extends JsonGeocoder { @@ -25,8 +26,8 @@ public class MapboxGeocoder extends JsonGeocoder { return "https://api.mapbox.com/geocoding/v5/mapbox.places/%2$f,%1$f.json?access_token=" + key; } - public MapboxGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key), cacheSize, addressFormat); + public MapboxGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java b/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java index 2b70708a1..dea295cca 100644 --- a/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java @@ -17,11 +17,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class MapmyIndiaGeocoder extends JsonGeocoder { - public MapmyIndiaGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "/" + key + "/rev_geocode?lat=%f&lng=%f", cacheSize, addressFormat); + public MapmyIndiaGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, url + "/" + key + "/rev_geocode?lat=%f&lng=%f", cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/NominatimGeocoder.java b/src/main/java/org/traccar/geocoder/NominatimGeocoder.java index 8db25bf15..b731549f7 100644 --- a/src/main/java/org/traccar/geocoder/NominatimGeocoder.java +++ b/src/main/java/org/traccar/geocoder/NominatimGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class NominatimGeocoder extends JsonGeocoder { @@ -33,8 +34,9 @@ public class NominatimGeocoder extends JsonGeocoder { return url; } - public NominatimGeocoder(String url, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key, language), cacheSize, addressFormat); + public NominatimGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java index bbcc00cd0..fb61440aa 100644 --- a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java +++ b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class OpenCageGeocoder extends JsonGeocoder { @@ -32,8 +33,9 @@ public class OpenCageGeocoder extends JsonGeocoder { return url; } - public OpenCageGeocoder(String url, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key, language), cacheSize, addressFormat); + public OpenCageGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java b/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java index 2674a68ca..9778d9eda 100644 --- a/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java +++ b/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class PositionStackGeocoder extends JsonGeocoder { @@ -24,8 +25,8 @@ public class PositionStackGeocoder extends JsonGeocoder { return "http://api.positionstack.com/v1/reverse?access_key=" + key + "&query=%f,%f"; } - public PositionStackGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key), cacheSize, addressFormat); + public PositionStackGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/TomTomGeocoder.java b/src/main/java/org/traccar/geocoder/TomTomGeocoder.java index 232b24396..9bb36efc2 100644 --- a/src/main/java/org/traccar/geocoder/TomTomGeocoder.java +++ b/src/main/java/org/traccar/geocoder/TomTomGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class TomTomGeocoder extends JsonGeocoder { @@ -28,8 +29,8 @@ public class TomTomGeocoder extends JsonGeocoder { return url; } - public TomTomGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key), cacheSize, addressFormat); + public TomTomGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java b/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java index 5901b47cd..8f0f3b704 100644 --- a/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.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. @@ -15,12 +15,14 @@ */ package org.traccar.geolocation; +import javax.ws.rs.client.Client; + public class GoogleGeolocationProvider extends UniversalGeolocationProvider { private static final String URL = "https://www.googleapis.com/geolocation/v1/geolocate"; - public GoogleGeolocationProvider(String key) { - super(URL, key); + public GoogleGeolocationProvider(Client client, String key) { + super(client, URL, key); } } diff --git a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java b/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java index c6a73a52b..3b4ba4e1f 100644 --- a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 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. @@ -15,12 +15,14 @@ */ package org.traccar.geolocation; +import javax.ws.rs.client.Client; + public class MozillaGeolocationProvider extends UniversalGeolocationProvider { private static final String URL = "https://location.services.mozilla.com/v1/geolocate"; - public MozillaGeolocationProvider(String key) { - super(URL, key != null ? key : "test"); + public MozillaGeolocationProvider(Client client, String key) { + super(client, URL, key != null ? key : "test"); } } diff --git a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index 2535970d3..82fcf42ab 100644 --- a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.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. @@ -15,18 +15,20 @@ */ package org.traccar.geolocation; -import org.traccar.Context; import org.traccar.model.CellTower; import org.traccar.model.Network; import javax.json.JsonObject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.InvocationCallback; public class OpenCellIdGeolocationProvider implements GeolocationProvider { - private String url; + private final Client client; + private final String url; - public OpenCellIdGeolocationProvider(String url, String key) { + public OpenCellIdGeolocationProvider(Client client, String url, String key) { + this.client = client; if (url == null) { url = "http://opencellid.org/cell/get"; } @@ -41,7 +43,7 @@ public class OpenCellIdGeolocationProvider implements GeolocationProvider { String request = String.format(url, cellTower.getMobileCountryCode(), cellTower.getMobileNetworkCode(), cellTower.getLocationAreaCode(), cellTower.getCellId()); - Context.getClient().target(request).request().async().get(new InvocationCallback() { + client.target(request).request().async().get(new InvocationCallback() { @Override public void completed(JsonObject json) { if (json.containsKey("lat") && json.containsKey("lon")) { diff --git a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java index 33cd84a47..7a3f71ee1 100644 --- a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 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. @@ -15,26 +15,26 @@ */ package org.traccar.geolocation; -import org.traccar.Context; import org.traccar.model.Network; import javax.json.JsonObject; -import javax.ws.rs.client.AsyncInvoker; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; public class UniversalGeolocationProvider implements GeolocationProvider { + private final Client client; private final String url; - public UniversalGeolocationProvider(String url, String key) { + public UniversalGeolocationProvider(Client client, String url, String key) { + this.client = client; this.url = url + "?key=" + key; } @Override public void getLocation(Network network, final LocationProviderCallback callback) { - AsyncInvoker invoker = Context.getClient().target(url).request().async(); - invoker.post(Entity.json(network), new InvocationCallback() { + client.target(url).request().async().post(Entity.json(network), new InvocationCallback() { @Override public void completed(JsonObject json) { if (json.containsKey("error")) { diff --git a/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java index 963bcb688..14893b6a3 100644 --- a/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 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. @@ -19,22 +19,23 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import org.traccar.Context; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.WifiAccessPoint; import javax.json.JsonObject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; import java.util.Collection; public class UnwiredGeolocationProvider implements GeolocationProvider { - private String url; - private String key; + private final Client client; + private final String url; + private final String key; - private ObjectMapper objectMapper; + private final ObjectMapper objectMapper; private abstract static class NetworkMixIn { @JsonProperty("mcc") @@ -73,7 +74,8 @@ public class UnwiredGeolocationProvider implements GeolocationProvider { abstract Integer getSignalStrength(); } - public UnwiredGeolocationProvider(String url, String key) { + public UnwiredGeolocationProvider(Client client, String url, String key) { + this.client = client; this.url = url; this.key = key; @@ -88,7 +90,7 @@ public class UnwiredGeolocationProvider implements GeolocationProvider { ObjectNode json = objectMapper.valueToTree(network); json.put("token", key); - Context.getClient().target(url).request().async().post(Entity.json(json), new InvocationCallback() { + client.target(url).request().async().post(Entity.json(json), new InvocationCallback() { @Override public void completed(JsonObject json) { if (json.getString("status").equals("error")) { diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index b0494d74d..5afff1b7b 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -17,10 +17,9 @@ package org.traccar.notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.UsersManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -28,6 +27,7 @@ import org.traccar.model.Maintenance; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; import javax.ws.rs.client.InvocationCallback; @@ -42,12 +42,16 @@ public class EventForwarder { private final String url; private final String header; + private final Client client; private final CacheManager cacheManager; + private final UsersManager usersManager; - public EventForwarder(Config config) { + public EventForwarder(Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { + this.client = client; + this.cacheManager = cacheManager; + this.usersManager = usersManager; url = config.getString(Keys.EVENT_FORWARD_URL); header = config.getString(Keys.EVENT_FORWARD_HEADERS); - cacheManager = Main.getInjector().getInstance(CacheManager.class); } private static final String KEY_POSITION = "position"; @@ -59,7 +63,7 @@ public class EventForwarder { public final void forwardEvent(Event event, Position position, Set users) { - Invocation.Builder requestBuilder = Context.getClient().target(url).request(); + Invocation.Builder requestBuilder = client.target(url).request(); if (header != null && !header.isEmpty()) { for (String line: header.split("\\r?\\n")) { @@ -105,7 +109,7 @@ public class EventForwarder { data.put(KEY_MAINTENANCE, maintenance); } } - data.put(KEY_USERS, Context.getUsersManager().getItems(users)); + data.put(KEY_USERS, usersManager.getItems(users)); return data; } diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 154de603a..6412a186a 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -15,24 +15,31 @@ */ package org.traccar.schedule; +import com.google.inject.Injector; import org.traccar.LifecycleObject; +import javax.inject.Inject; import javax.inject.Singleton; +import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @Singleton public class ScheduleManager implements LifecycleObject { + private final Injector injector; private ScheduledExecutorService executor; + @Inject + public ScheduleManager(Injector injector) { + this.injector = injector; + } + @Override public void start() { executor = Executors.newSingleThreadScheduledExecutor(); - - new TaskDeviceInactivityCheck().schedule(executor); - new TaskWebSocketKeepalive().schedule(executor); - new TaskHealthCheck().schedule(executor); + List.of(TaskDeviceInactivityCheck.class, TaskWebSocketKeepalive.class, TaskHealthCheck.class) + .forEach(task -> injector.getInstance(task).schedule(executor)); } @Override diff --git a/src/main/java/org/traccar/schedule/ScheduleTask.java b/src/main/java/org/traccar/schedule/ScheduleTask.java new file mode 100644 index 000000000..1b537213b --- /dev/null +++ b/src/main/java/org/traccar/schedule/ScheduleTask.java @@ -0,0 +1,22 @@ +/* + * 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.schedule; + +import java.util.concurrent.ScheduledExecutorService; + +public interface ScheduleTask extends Runnable { + void schedule(ScheduledExecutorService executor); +} diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index 80641d7d4..f2ed3c3b3 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.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. @@ -15,17 +15,19 @@ */ package org.traccar.schedule; -import org.traccar.Context; +import org.traccar.database.DeviceManager; +import org.traccar.database.NotificationManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskDeviceInactivityCheck implements Runnable { +public class TaskDeviceInactivityCheck implements ScheduleTask { public static final String ATTRIBUTE_DEVICE_INACTIVITY_START = "deviceInactivityStart"; public static final String ATTRIBUTE_DEVICE_INACTIVITY_PERIOD = "deviceInactivityPeriod"; @@ -33,6 +35,16 @@ public class TaskDeviceInactivityCheck implements Runnable { private static final long CHECK_PERIOD_MINUTES = 15; + private final DeviceManager deviceManager; + private final NotificationManager notificationManager; + + @Inject + public TaskDeviceInactivityCheck(DeviceManager deviceManager, NotificationManager notificationManager) { + this.deviceManager = deviceManager; + this.notificationManager = notificationManager; + } + + @Override public void schedule(ScheduledExecutorService executor) { executor.scheduleAtFixedRate(this, CHECK_PERIOD_MINUTES, CHECK_PERIOD_MINUTES, TimeUnit.MINUTES); } @@ -43,7 +55,7 @@ public class TaskDeviceInactivityCheck implements Runnable { long checkPeriod = TimeUnit.MINUTES.toMillis(CHECK_PERIOD_MINUTES); Map events = new HashMap<>(); - for (Device device : Context.getDeviceManager().getAllDevices()) { + for (Device device : deviceManager.getAllDevices()) { if (device.getLastUpdate() != null && checkDevice(device, currentTime, checkPeriod)) { Event event = new Event(Event.TYPE_DEVICE_INACTIVE, device.getId()); event.set(ATTRIBUTE_LAST_UPDATE, device.getLastUpdate().getTime()); @@ -51,7 +63,7 @@ public class TaskDeviceInactivityCheck implements Runnable { } } - Context.getNotificationManager().updateEvents(events); + notificationManager.updateEvents(events); } private boolean checkDevice(Device device, long currentTime, long checkPeriod) { diff --git a/src/main/java/org/traccar/schedule/TaskHealthCheck.java b/src/main/java/org/traccar/schedule/TaskHealthCheck.java index 087cd3e63..a8c9873ce 100644 --- a/src/main/java/org/traccar/schedule/TaskHealthCheck.java +++ b/src/main/java/org/traccar/schedule/TaskHealthCheck.java @@ -19,23 +19,31 @@ import com.sun.jna.Library; import com.sun.jna.Native; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskHealthCheck implements Runnable { +public class TaskHealthCheck implements ScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskHealthCheck.class); + private final Config config; + private final Client client; + private SystemD systemD; private boolean enabled; private long period; - public TaskHealthCheck() { - if (!Context.getConfig().getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) + @Inject + public TaskHealthCheck(Config config, Client client) { + this.config = config; + this.client = client; + if (!config.getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) && System.getProperty("os.name").toLowerCase().startsWith("linux")) { try { systemD = Native.load("systemd", SystemD.class); @@ -54,11 +62,12 @@ public class TaskHealthCheck implements Runnable { } private String getUrl() { - String address = Context.getConfig().getString(Keys.WEB_ADDRESS, "localhost"); - int port = Context.getConfig().getInteger(Keys.WEB_PORT); + String address = config.getString(Keys.WEB_ADDRESS, "localhost"); + int port = config.getInteger(Keys.WEB_PORT); return "http://" + address + ":" + port + "/api/server"; } + @Override public void schedule(ScheduledExecutorService executor) { if (enabled) { executor.scheduleAtFixedRate(this, period, period, TimeUnit.MILLISECONDS); @@ -68,7 +77,7 @@ public class TaskHealthCheck implements Runnable { @Override public void run() { LOGGER.debug("Health check running"); - int status = Context.getClient().target(getUrl()).request().get().getStatus(); + int status = client.target(getUrl()).request().get().getStatus(); if (status == 200) { int result = systemD.sd_notify(0, "WATCHDOG=1"); if (result < 0) { diff --git a/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java b/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java index 953b0efea..e6c2e8b6d 100644 --- a/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java +++ b/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.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. @@ -15,22 +15,31 @@ */ package org.traccar.schedule; -import org.traccar.Context; +import org.traccar.session.ConnectionManager; +import javax.inject.Inject; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskWebSocketKeepalive implements Runnable { +public class TaskWebSocketKeepalive implements ScheduleTask { private static final long PERIOD_SECONDS = 55; + private final ConnectionManager connectionManager; + + @Inject + public TaskWebSocketKeepalive(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; + } + + @Override public void schedule(ScheduledExecutorService executor) { executor.scheduleAtFixedRate(this, PERIOD_SECONDS, PERIOD_SECONDS, TimeUnit.SECONDS); } @Override public void run() { - Context.getConnectionManager().sendKeepalive(); + connectionManager.sendKeepalive(); } } diff --git a/src/main/java/org/traccar/sms/HttpSmsClient.java b/src/main/java/org/traccar/sms/HttpSmsClient.java index 5c3cef747..51b161594 100644 --- a/src/main/java/org/traccar/sms/HttpSmsClient.java +++ b/src/main/java/org/traccar/sms/HttpSmsClient.java @@ -16,11 +16,12 @@ */ package org.traccar.sms; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; import org.traccar.notification.MessageException; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; import javax.ws.rs.core.MediaType; @@ -31,6 +32,7 @@ import java.nio.charset.StandardCharsets; public class HttpSmsClient implements SmsManager { + private final Client client; private final String url; private final String authorizationHeader; private final String authorization; @@ -38,14 +40,15 @@ public class HttpSmsClient implements SmsManager { private final boolean encode; private final MediaType mediaType; - public HttpSmsClient() { - url = Context.getConfig().getString(Keys.SMS_HTTP_URL); - authorizationHeader = Context.getConfig().getString(Keys.SMS_HTTP_AUTHORIZATION_HEADER); - if (Context.getConfig().hasKey(Keys.SMS_HTTP_AUTHORIZATION)) { - authorization = Context.getConfig().getString(Keys.SMS_HTTP_AUTHORIZATION); + public HttpSmsClient(Config config, Client client) { + this.client = client; + url = config.getString(Keys.SMS_HTTP_URL); + authorizationHeader = config.getString(Keys.SMS_HTTP_AUTHORIZATION_HEADER); + if (config.hasKey(Keys.SMS_HTTP_AUTHORIZATION)) { + authorization = config.getString(Keys.SMS_HTTP_AUTHORIZATION); } else { - String user = Context.getConfig().getString(Keys.SMS_HTTP_USER); - String password = Context.getConfig().getString(Keys.SMS_HTTP_PASSWORD); + String user = config.getString(Keys.SMS_HTTP_USER); + String password = config.getString(Keys.SMS_HTTP_PASSWORD); if (user != null && password != null) { authorization = "Basic " + DataConverter.printBase64((user + ":" + password).getBytes(StandardCharsets.UTF_8)); @@ -53,7 +56,7 @@ public class HttpSmsClient implements SmsManager { authorization = null; } } - template = Context.getConfig().getString(Keys.SMS_HTTP_TEMPLATE).trim(); + template = config.getString(Keys.SMS_HTTP_TEMPLATE).trim(); if (template.charAt(0) == '{' || template.charAt(0) == '[') { encode = false; mediaType = MediaType.APPLICATION_JSON_TYPE; @@ -78,7 +81,7 @@ public class HttpSmsClient implements SmsManager { } private Invocation.Builder getRequestBuilder() { - Invocation.Builder builder = Context.getClient().target(url).request(); + Invocation.Builder builder = client.target(url).request(); if (authorization != null) { builder = builder.header(authorizationHeader, authorization); } diff --git a/src/main/java/org/traccar/sms/SnsSmsClient.java b/src/main/java/org/traccar/sms/SnsSmsClient.java index 49889ac89..ed5a325cc 100644 --- a/src/main/java/org/traccar/sms/SnsSmsClient.java +++ b/src/main/java/org/traccar/sms/SnsSmsClient.java @@ -27,7 +27,7 @@ import com.amazonaws.services.sns.model.PublishRequest; import com.amazonaws.services.sns.model.PublishResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.util.HashMap; @@ -38,19 +38,12 @@ public class SnsSmsClient implements SmsManager { private final AmazonSNSAsync snsClient; - public SnsSmsClient() { - if (Context.getConfig().hasKey(Keys.SMS_AWS_REGION) - && Context.getConfig().hasKey(Keys.SMS_AWS_ACCESS) - && Context.getConfig().hasKey(Keys.SMS_AWS_SECRET)) { - BasicAWSCredentials awsCredentials = - new BasicAWSCredentials(Context.getConfig().getString(Keys.SMS_AWS_ACCESS), - Context.getConfig().getString(Keys.SMS_AWS_SECRET)); - snsClient = AmazonSNSAsyncClientBuilder.standard() - .withRegion(Context.getConfig().getString(Keys.SMS_AWS_REGION)) - .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).build(); - } else { - throw new RuntimeException("SNS Not Configured Properly. Please provide valid config."); - } + public SnsSmsClient(Config config) { + BasicAWSCredentials awsCredentials = new BasicAWSCredentials( + config.getString(Keys.SMS_AWS_ACCESS), config.getString(Keys.SMS_AWS_SECRET)); + snsClient = AmazonSNSAsyncClientBuilder.standard() + .withRegion(config.getString(Keys.SMS_AWS_REGION)) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).build(); } @Override @@ -64,11 +57,12 @@ public class SnsSmsClient implements SmsManager { PublishRequest publishRequest = new PublishRequest().withMessage(message) .withPhoneNumber(destAddress).withMessageAttributes(smsAttributes); - snsClient.publishAsync(publishRequest, new AsyncHandler() { + snsClient.publishAsync(publishRequest, new AsyncHandler<>() { @Override public void onError(Exception exception) { LOGGER.error("SMS send failed", exception); } + @Override public void onSuccess(PublishRequest request, PublishResult result) { } diff --git a/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java b/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java index 429a47c76..edf089f37 100644 --- a/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java +++ b/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.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. @@ -15,19 +15,21 @@ */ package org.traccar.speedlimit; -import org.traccar.Context; import org.traccar.helper.UnitsConverter; import javax.json.JsonArray; import javax.json.JsonObject; import javax.ws.rs.client.AsyncInvoker; +import javax.ws.rs.client.Client; import javax.ws.rs.client.InvocationCallback; public class OverpassSpeedLimitProvider implements SpeedLimitProvider { + private final Client client; private final String url; - public OverpassSpeedLimitProvider(String url) { + public OverpassSpeedLimitProvider(Client client, String url) { + this.client = client; this.url = url + "?data=[out:json];way[maxspeed](around:100.0,%f,%f);out%%20tags;"; } @@ -46,7 +48,7 @@ public class OverpassSpeedLimitProvider implements SpeedLimitProvider { @Override public void getSpeedLimit(double latitude, double longitude, SpeedLimitProviderCallback callback) { String formattedUrl = String.format(url, latitude, longitude); - AsyncInvoker invoker = Context.getClient().target(formattedUrl).request().async(); + AsyncInvoker invoker = client.target(formattedUrl).request().async(); invoker.get(new InvocationCallback() { @Override public void completed(JsonObject json) { diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 6a85777b1..ff33b1f1c 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -3,6 +3,8 @@ package org.traccar.geocoder; import org.junit.Ignore; import org.junit.Test; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; import java.util.Locale; import static org.junit.Assert.assertEquals; @@ -13,10 +15,12 @@ public class GeocoderTest { Locale.setDefault(Locale.US); } + private final Client client = ClientBuilder.newClient(); + @Ignore @Test public void testGoogle() { - Geocoder geocoder = new GoogleGeocoder(null, null, 0, new AddressFormat()); + Geocoder geocoder = new GoogleGeocoder(client, null, null, 0, new AddressFormat()); String address = geocoder.getAddress(31.776797, 35.211489, null); assertEquals("1 Ibn Shaprut St, Jerusalem, Jerusalem District, IL", address); } @@ -24,7 +28,7 @@ public class GeocoderTest { @Ignore @Test public void testNominatim() { - Geocoder geocoder = new NominatimGeocoder(null, null, null, 0, new AddressFormat()); + Geocoder geocoder = new NominatimGeocoder(client, null, null, null, 0, new AddressFormat()); String address = geocoder.getAddress(40.7337807, -73.9974401, null); assertEquals("35 West 9th Street, NYC, New York, US", address); } @@ -32,7 +36,7 @@ public class GeocoderTest { @Ignore @Test public void testGisgraphy() { - Geocoder geocoder = new GisgraphyGeocoder(null, 0, new AddressFormat()); + Geocoder geocoder = new GisgraphyGeocoder(client, null, 0, new AddressFormat()); String address = geocoder.getAddress(48.8530000, 2.3400000, null); assertEquals("Rue du Jardinet, Paris, Île-de-France, FR", address); } @@ -41,7 +45,7 @@ public class GeocoderTest { @Test public void testOpenCage() { Geocoder geocoder = new OpenCageGeocoder( - "http://api.opencagedata.com/geocode/v1", "SECRET", null, 0, new AddressFormat()); + client, "http://api.opencagedata.com/geocode/v1", "SECRET", null, 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("Charleston Road, California, US", address); } @@ -49,7 +53,7 @@ public class GeocoderTest { @Ignore @Test public void testGeocodeFarm() { - Geocoder geocoder = new GeocodeFarmGeocoder(null, null, 0, new AddressFormat()); + Geocoder geocoder = new GeocodeFarmGeocoder(client, null, null, 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("Estrella Avenue, Arcadia, California, United States", address); } @@ -57,7 +61,7 @@ public class GeocoderTest { @Ignore @Test public void testGeocodeXyz() { - Geocoder geocoder = new GeocodeXyzGeocoder(null, 0, new AddressFormat()); + Geocoder geocoder = new GeocodeXyzGeocoder(client, null, 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("605 ESTRELLA AVE, ARCADIA, California United States of America, US", address); } @@ -65,7 +69,7 @@ public class GeocoderTest { @Ignore @Test public void testBan() { - Geocoder geocoder = new BanGeocoder(0, new AddressFormat("%f [%d], %c")); + Geocoder geocoder = new BanGeocoder(client, 0, new AddressFormat("%f [%d], %c")); String address = geocoder.getAddress(48.8575, 2.2944, null); assertEquals("8 Avenue Gustave Eiffel 75007 Paris [75, Paris, Île-de-France], FR", address); } @@ -73,7 +77,7 @@ public class GeocoderTest { @Ignore @Test public void testHere() { - Geocoder geocoder = new HereGeocoder(null, "", "", null, 0, new AddressFormat()); + Geocoder geocoder = new HereGeocoder(client, null, "", "", null, 0, new AddressFormat()); String address = geocoder.getAddress(48.8575, 2.2944, null); assertEquals("6 Avenue Gustave Eiffel, Paris, Île-de-France, FRA", address); } @@ -81,7 +85,7 @@ public class GeocoderTest { @Ignore @Test public void testMapmyIndia() { - Geocoder geocoder = new MapmyIndiaGeocoder("", "", 0, new AddressFormat("%f")); + Geocoder geocoder = new MapmyIndiaGeocoder(client, "", "", 0, new AddressFormat("%f")); String address = geocoder.getAddress(28.6129602407977, 77.2294557094574, null); assertEquals("New Delhi, Delhi. 1 m from India Gate pin-110001 (India)", address); } @@ -89,7 +93,7 @@ public class GeocoderTest { @Ignore @Test public void testPositionStack() { - Geocoder geocoder = new PositionStackGeocoder("", 0, new AddressFormat("%f")); + Geocoder geocoder = new PositionStackGeocoder(client, "", 0, new AddressFormat("%f")); String address = geocoder.getAddress(28.6129602407977, 77.2294557094574, null); assertEquals("India Gate, New Delhi, India", address); } @@ -97,7 +101,7 @@ public class GeocoderTest { @Ignore @Test public void testMapbox() { - Geocoder geocoder = new MapboxGeocoder("", 0, new AddressFormat("%f")); + Geocoder geocoder = new MapboxGeocoder(client, "", 0, new AddressFormat("%f")); String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("120 East 13th Street, New York, New York 10003, United States", address); } @@ -105,7 +109,7 @@ public class GeocoderTest { @Ignore @Test public void testMapTiler() { - Geocoder geocoder = new MapTilerGeocoder("", 0, new AddressFormat()); + Geocoder geocoder = new MapTilerGeocoder(client, "", 0, new AddressFormat()); String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("East 13th Street, New York City, New York, United States", address); } @@ -113,7 +117,7 @@ public class GeocoderTest { @Ignore @Test public void testGeoapify() { - Geocoder geocoder = new GeoapifyGeocoder("", null, 0, new AddressFormat()); + Geocoder geocoder = new GeoapifyGeocoder(client, "", null, 0, new AddressFormat()); String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("114 East 13th Street, New York, New York, US", address); } diff --git a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java index 2729052d6..1ceac41cc 100644 --- a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java +++ b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java @@ -6,19 +6,24 @@ import org.traccar.BaseTest; import org.traccar.model.CellTower; import org.traccar.model.Network; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class GeolocationProviderTest extends BaseTest { + private final Client client = ClientBuilder.newClient(); + @Ignore @Test public void test() throws Exception { - testLocationProvider(); + testMozilla(); } - public void testLocationProvider() throws Exception { - MozillaGeolocationProvider provider = new MozillaGeolocationProvider(null); + public void testMozilla() throws Exception { + MozillaGeolocationProvider provider = new MozillaGeolocationProvider(client, null); Network network = new Network(CellTower.from(208, 1, 2, 1234567)); diff --git a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java index dcac78f80..aa0be23cf 100644 --- a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java +++ b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java @@ -3,19 +3,24 @@ package org.traccar.speedlimit; import org.junit.Ignore; import org.junit.Test; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class OverpassSpeedLimitProviderTest { + private final Client client = ClientBuilder.newClient(); + @Ignore @Test public void test() throws Exception { - testLocationProvider(); + testOverpass(); } - public void testLocationProvider() throws Exception { - SpeedLimitProvider provider = new OverpassSpeedLimitProvider("http://8.8.8.8/api/interpreter"); + public void testOverpass() throws Exception { + SpeedLimitProvider provider = new OverpassSpeedLimitProvider(client, "http://8.8.8.8/api/interpreter"); provider.getSpeedLimit(34.74767, -82.48098, new SpeedLimitProvider.SpeedLimitProviderCallback() { @Override -- cgit v1.2.3 From 9c9e62bdba68a1f1d29cd5082ffd47eb1f46dab9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 15:50:37 -0700 Subject: Fix injection --- src/main/java/org/traccar/MainModule.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 2c88dbc13..ed54853ed 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -117,6 +117,11 @@ public class MainModule extends AbstractModule { return Context.getDataManager(); } + @Provides + public static UsersManager provideUsersManager() { + return Context.getUsersManager(); + } + @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); -- cgit v1.2.3 From 0d7985bd502ae106c5c7afcd2b8263058b090e5f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 16:22:29 -0700 Subject: Another injection fix --- src/main/java/org/traccar/MainModule.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index ed54853ed..0b3275cfc 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,6 +30,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.database.NotificationManager; import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; @@ -122,6 +123,11 @@ public class MainModule extends AbstractModule { return Context.getUsersManager(); } + @Provides + public static NotificationManager provideNotificationManager() { + return Context.getNotificationManager(); + } + @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); -- cgit v1.2.3 From 69d634fb0723ca4dced2f15ea432b4eb59d11d8e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 19:09:42 -0700 Subject: Add server overlay URL --- schema/changelog-5.1.xml | 4 ++++ src/main/java/org/traccar/model/Server.java | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'src/main/java/org') diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml index 26c2088b9..d5a8bc1fe 100644 --- a/schema/changelog-5.1.xml +++ b/schema/changelog-5.1.xml @@ -12,6 +12,10 @@ + + + + diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index c5640fb97..ee7f7069a 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -85,6 +85,16 @@ public class Server extends ExtendedModel implements UserRestrictions { this.mapUrl = mapUrl; } + private String overlayUrl; + + public String getOverlayUrl() { + return overlayUrl; + } + + public void setOverlayUrl(String overlayUrl) { + this.overlayUrl = overlayUrl; + } + private double latitude; public double getLatitude() { -- cgit v1.2.3 From 62680cbdc4c26e9729aad3c768e5680b27b91e64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 12 Jun 2022 10:40:53 -0700 Subject: Revert JSR353 removal --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 46227d1ff..8c196043a 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,7 @@ dependencies { implementation "org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion" implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" implementation "org.liquibase:liquibase-core:4.7.0" implementation "com.sun.mail:javax.mail:1.6.2" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 0b3275cfc..73fe0c460 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -17,6 +17,7 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Provides; @@ -98,6 +99,7 @@ public class MainModule extends AbstractModule { if (config.getBoolean(Keys.WEB_SANITIZE)) { objectMapper.registerModule(new SanitizerModule()); } + objectMapper.registerModule(new JSR353Module()); objectMapper.setConfig(objectMapper .getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); return objectMapper; -- cgit v1.2.3 From e894c17cf14addb729a6c51712ef672cc2cd160b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 17:19:15 -0700 Subject: Refactor getPositions method --- .../org/traccar/api/resource/PositionResource.java | 10 +++++++--- src/main/java/org/traccar/database/DataManager.java | 9 --------- .../java/org/traccar/helper/model/PositionUtil.java | 19 +++++++++++++++++++ .../java/org/traccar/reports/RouteReportProvider.java | 11 +++++++---- .../java/org/traccar/reports/StopsReportProvider.java | 8 ++++++-- .../org/traccar/reports/SummaryReportProvider.java | 10 ++++++---- .../java/org/traccar/reports/TripsReportProvider.java | 14 ++++++-------- 7 files changed, 51 insertions(+), 30 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 2618a04cb..ae948ee14 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -17,9 +17,13 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -29,7 +33,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.List; @@ -57,9 +60,10 @@ public class PositionResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); if (from != null && to != null) { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); - return Context.getDataManager().getPositions(deviceId, from, to); + return PositionUtil.getPositions(storage, deviceId, from, to); } else { - return Collections.singleton(Context.getDeviceManager().getLastPosition(deviceId)); + return storage.getObjects(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions(deviceId))); } } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 556f1e348..93c6861e6 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -176,15 +176,6 @@ public class DataManager { new Condition.Equals("id", "id"))); } - public Collection getPositions(long deviceId, Date from, Date to) throws StorageException { - return storage.getObjects(Position.class, new Request( - new Columns.All(), - new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), - new Condition.Between("fixTime", "from", from, "to", to)), - new Order("fixTime"))); - } - public Position getPrecedingPosition(long deviceId, Date date) throws StorageException { return storage.getObject(Position.class, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 644517dac..566e31bc5 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -17,6 +17,15 @@ package org.traccar.helper.model; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; + +import java.util.Date; +import java.util.List; public final class PositionUtil { @@ -41,4 +50,14 @@ public final class PositionUtil { return distance; } + public static List getPositions( + Storage storage, long deviceId, Date from, Date to) throws StorageException { + return storage.getObjects(Position.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Between("fixTime", "from", from, "to", to)), + new Order("fixTime"))); + } + } diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 136a154aa..dbbf0906d 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -18,11 +18,13 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -37,10 +39,12 @@ import java.util.Date; public class RouteReportProvider { private final ReportUtils reportUtils; + private final Storage storage; @Inject - public RouteReportProvider(ReportUtils reportUtils) { + public RouteReportProvider(ReportUtils reportUtils, Storage storage) { this.reportUtils = reportUtils; + this.storage = storage; } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, @@ -49,7 +53,7 @@ public class RouteReportProvider { ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); + result.addAll(PositionUtil.getPositions(storage, deviceId, from, to)); } return result; } @@ -62,8 +66,7 @@ public class RouteReportProvider { ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection positions = Context.getDataManager() - .getPositions(deviceId, from, to); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 807a6133b..534ab7742 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -18,11 +18,13 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -37,17 +39,19 @@ import java.util.Date; public class StopsReportProvider { private final ReportUtils reportUtils; + private final Storage storage; @Inject - public StopsReportProvider(ReportUtils reportUtils) { + public StopsReportProvider(ReportUtils reportUtils, Storage storage) { this.reportUtils = reportUtils; + this.storage = storage; } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); return reportUtils.detectTripsAndStops( - Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, StopReportItem.class); + PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, StopReportItem.class); } public Collection getObjects( diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 28abe790b..25d558480 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -25,6 +25,7 @@ import org.traccar.helper.model.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -41,11 +42,13 @@ public class SummaryReportProvider { private final ReportUtils reportUtils; private final PermissionsService permissionsService; + private final Storage storage; @Inject - public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService) { + public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService, Storage storage) { this.reportUtils = reportUtils; this.permissionsService = permissionsService; + this.storage = storage; } private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { @@ -111,9 +114,8 @@ public class SummaryReportProvider { private Collection calculateSummaryResults( long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { - ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); - - ArrayList results = new ArrayList<>(); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + var results = new ArrayList(); if (daily && !positions.isEmpty()) { int startIndex = 0; int startDay = getDay(userId, positions.iterator().next().getFixTime()); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 5e598cb50..a8e0e3dde 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -18,14 +18,13 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -40,21 +39,20 @@ import java.util.Date; public class TripsReportProvider { private final ReportUtils reportUtils; + private final Storage storage; @Inject - public TripsReportProvider(ReportUtils reportUtils) { + public TripsReportProvider(ReportUtils reportUtils, Storage storage) { this.reportUtils = reportUtils; + this.storage = storage; } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - return reportUtils.detectTripsAndStops( - Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, TripReportItem.class); + PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, TripReportItem.class); } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, -- cgit v1.2.3 From 8569e396f7bdafd49a974b35a2e83a57164c6c62 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 18:49:01 -0700 Subject: Remove report template path key --- .../java/org/traccar/reports/EventsReportProvider.java | 14 ++++++++++---- .../java/org/traccar/reports/RouteReportProvider.java | 14 ++++++++++---- .../java/org/traccar/reports/StopsReportProvider.java | 14 ++++++++++---- .../java/org/traccar/reports/SummaryReportProvider.java | 15 +++++++++++---- .../java/org/traccar/reports/TripsReportProvider.java | 14 ++++++++++---- 5 files changed, 51 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 6de313a13..91d061c65 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -28,10 +30,12 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -40,10 +44,12 @@ import java.util.Iterator; public class EventsReportProvider { + private final Config config; private final ReportUtils reportUtils; @Inject - public EventsReportProvider(ReportUtils reportUtils) { + public EventsReportProvider(Config config, ReportUtils reportUtils) { + this.config = config; this.reportUtils = reportUtils; } @@ -120,9 +126,9 @@ public class EventsReportProvider { deviceEvents.setObjects(events); devicesEvents.add(deviceEvents); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "events.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesEvents); context.putVar("sheetNames", sheetNames); diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index dbbf0906d..b1a806960 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -28,21 +30,25 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; public class RouteReportProvider { + private final Config config; private final ReportUtils reportUtils; private final Storage storage; @Inject - public RouteReportProvider(ReportUtils reportUtils, Storage storage) { + public RouteReportProvider(Config config, ReportUtils reportUtils, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.storage = storage; } @@ -80,9 +86,9 @@ public class RouteReportProvider { deviceRoutes.setObjects(positions); devicesRoutes.add(deviceRoutes); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "route.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesRoutes); context.putVar("sheetNames", sheetNames); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 534ab7742..a6a9a94cc 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -28,21 +30,25 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; public class StopsReportProvider { + private final Config config; private final ReportUtils reportUtils; private final Storage storage; @Inject - public StopsReportProvider(ReportUtils reportUtils, Storage storage) { + public StopsReportProvider(Config config, ReportUtils reportUtils, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.storage = storage; } @@ -88,9 +94,9 @@ public class StopsReportProvider { deviceStops.setObjects(stops); devicesStops.add(deviceStops); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "stops.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesStops); context.putVar("sheetNames", sheetNames); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 25d558480..68976b987 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -19,6 +19,8 @@ package org.traccar.reports; import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.api.security.PermissionsService; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; @@ -29,10 +31,12 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -40,12 +44,15 @@ import java.util.Date; public class SummaryReportProvider { + private final Config config; private final ReportUtils reportUtils; private final PermissionsService permissionsService; private final Storage storage; @Inject - public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService, Storage storage) { + public SummaryReportProvider( + Config config, ReportUtils reportUtils, PermissionsService permissionsService, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.permissionsService = permissionsService; this.storage = storage; @@ -157,9 +164,9 @@ public class SummaryReportProvider { Date from, Date to, boolean daily) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "summary.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("summaries", summaries); context.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index a8e0e3dde..bff559664 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -28,21 +30,25 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; public class TripsReportProvider { + private final Config config; private final ReportUtils reportUtils; private final Storage storage; @Inject - public TripsReportProvider(ReportUtils reportUtils, Storage storage) { + public TripsReportProvider(Config config, ReportUtils reportUtils, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.storage = storage; } @@ -88,9 +94,9 @@ public class TripsReportProvider { deviceTrips.setObjects(trips); devicesTrips.add(deviceTrips); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "trips.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesTrips); context.putVar("sheetNames", sheetNames); -- cgit v1.2.3 From a4f47f67b654cbfd59a134ed3a621f75b35ad7af Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 18:55:34 -0700 Subject: Refactor getEvents method --- .../java/org/traccar/database/DataManager.java | 10 ---------- .../org/traccar/reports/EventsReportProvider.java | 23 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 13 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 93c6861e6..4fd0cd8c1 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -31,7 +31,6 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Event; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; @@ -205,15 +204,6 @@ public class DataManager { return storage.getObject(Server.class, new Request(new Columns.All())); } - public Collection getEvents(long deviceId, Date from, Date to) throws StorageException { - return storage.getObjects(Event.class, new Request( - new Columns.All(), - new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), - new Condition.Between("eventTime", "from", from, "to", to)), - new Order("eventTime"))); - } - public Collection getStatistics(Date from, Date to) throws StorageException { return storage.getObjects(Statistics.class, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 91d061c65..5148695a9 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -27,7 +27,12 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -41,16 +46,28 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import java.util.List; public class EventsReportProvider { private final Config config; private final ReportUtils reportUtils; + private final Storage storage; @Inject - public EventsReportProvider(Config config, ReportUtils reportUtils) { + public EventsReportProvider(Config config, ReportUtils reportUtils, Storage storage) { this.config = config; this.reportUtils = reportUtils; + this.storage = storage; + } + + private List getEvents(long deviceId, Date from, Date to) throws StorageException { + return storage.getObjects(Event.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Between("eventTime", "from", from, "to", to)), + new Order("eventTime"))); } public Collection getObjects( @@ -60,7 +77,7 @@ public class EventsReportProvider { ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); + Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Event event : events) { if (all || types.contains(event.getType())) { @@ -87,7 +104,7 @@ public class EventsReportProvider { HashMap maintenanceNames = new HashMap<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); + Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { Event event = iterator.next(); -- cgit v1.2.3 From 6433ec663ec79196714dcd99939cdddf81f77a7a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 18:57:19 -0700 Subject: Refactor getStatistics method --- .../java/org/traccar/api/resource/StatisticsResource.java | 14 ++++++++++---- src/main/java/org/traccar/database/DataManager.java | 8 -------- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/StatisticsResource.java b/src/main/java/org/traccar/api/resource/StatisticsResource.java index 5c0734877..1f2296f28 100644 --- a/src/main/java/org/traccar/api/resource/StatisticsResource.java +++ b/src/main/java/org/traccar/api/resource/StatisticsResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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. @@ -15,10 +15,13 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Statistics; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -37,8 +40,11 @@ public class StatisticsResource extends BaseResource { @GET public Collection get( @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); - return Context.getDataManager().getStatistics(from, to); + permissionsService.checkAdmin(getUserId()); + return storage.getObjects(Statistics.class, new Request( + new Columns.All(), + new Condition.Between("captureTime", "from", from, "to", to), + new Order("captureTime"))); } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 4fd0cd8c1..8ed907fdd 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -34,7 +34,6 @@ import org.traccar.model.Device; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; -import org.traccar.model.Statistics; import org.traccar.model.User; import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; @@ -204,13 +203,6 @@ public class DataManager { return storage.getObject(Server.class, new Request(new Columns.All())); } - public Collection getStatistics(Date from, Date to) throws StorageException { - return storage.getObjects(Statistics.class, new Request( - new Columns.All(), - new Condition.Between("captureTime", "from", from, "to", to), - new Order("captureTime"))); - } - public Collection getPermissions(Class owner, Class property) throws StorageException, ClassNotFoundException { return storage.getPermissions(owner, property); -- cgit v1.2.3 From dd2594ddce22e105a6d9cb356c3c22c3227e58f9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 19:03:37 -0700 Subject: Remove data manager methods --- .../java/org/traccar/api/resource/EventResource.java | 6 +++++- .../org/traccar/api/resource/PermissionsResource.java | 6 ++---- .../java/org/traccar/api/resource/PositionResource.java | 3 ++- src/main/java/org/traccar/api/resource/UserResource.java | 3 ++- src/main/java/org/traccar/database/DataManager.java | 16 ---------------- 5 files changed, 11 insertions(+), 23 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 38b101b25..eb373946a 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -19,6 +19,9 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Event; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -37,7 +40,8 @@ public class EventResource extends BaseResource { @Path("{id}") @GET public Event get(@PathParam("id") long id) throws StorageException { - Event event = Context.getDataManager().getObject(Event.class, id); + Event event = storage.getObject(Event.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); if (event == null) { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index a4db6754c..36ee0c213 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -70,8 +70,7 @@ public class PermissionsResource extends BaseResource { for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); checkPermission(permission, true); - Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId(), true); + storage.addPermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), @@ -96,8 +95,7 @@ public class PermissionsResource extends BaseResource { for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); checkPermission(permission, false); - Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId(), false); + storage.removePermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index ae948ee14..2c0724df8 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -49,7 +49,8 @@ public class PositionResource extends BaseResource { if (!positionIds.isEmpty()) { ArrayList positions = new ArrayList<>(); for (Long positionId : positionIds) { - Position position = Context.getDataManager().getObject(Position.class, positionId); + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", positionId))); Context.getPermissionsManager().checkDevice(getUserId(), position.getDeviceId()); positions.add(position); } diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 83bb8fd0b..84f41ca1a 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -21,6 +21,7 @@ import org.traccar.config.Keys; import org.traccar.database.UsersManager; import org.traccar.helper.LogAction; import org.traccar.model.ManagedUser; +import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; @@ -86,7 +87,7 @@ public class UserResource extends BaseObjectResource { Context.getUsersManager().addItem(entity); LogAction.create(getUserId(), entity); if (Context.getPermissionsManager().getUserManager(getUserId())) { - Context.getDataManager().linkObject(User.class, getUserId(), ManagedUser.class, entity.getId(), true); + storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); } Context.getUsersManager().refreshUserItems(); diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 8ed907fdd..fd45a0321 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -208,22 +208,6 @@ public class DataManager { return storage.getPermissions(owner, property); } - public void linkObject( - Class owner, long ownerId, - Class property, long propertyId, boolean link) throws StorageException { - if (link) { - storage.addPermission(new Permission(owner, ownerId, property, propertyId)); - } else { - storage.removePermission(new Permission(owner, ownerId, property, propertyId)); - } - } - - public T getObject(Class clazz, long entityId) throws StorageException { - return storage.getObject(clazz, new Request( - new Columns.All(), - new Condition.Equals("id", "id", entityId))); - } - public Collection getObjects(Class clazz) throws StorageException { return storage.getObjects(clazz, new Request(new Columns.All())); } -- cgit v1.2.3 From e43169b2677ea9f07154247ce7ff726d046e59e2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 19:16:46 -0700 Subject: Refactor position resource --- .../org/traccar/api/resource/PositionResource.java | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 2c0724df8..099d97632 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -15,10 +15,12 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.model.PositionUtil; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -35,6 +37,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; @Path("positions") @Produces(MediaType.APPLICATION_JSON) @@ -47,18 +50,16 @@ public class PositionResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { if (!positionIds.isEmpty()) { - ArrayList positions = new ArrayList<>(); - for (Long positionId : positionIds) { + var positions = new ArrayList(); + for (long positionId : positionIds) { Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", positionId))); - Context.getPermissionsManager().checkDevice(getUserId(), position.getDeviceId()); + permissionsService.checkPermission(Device.class, getUserId(), position.getDeviceId()); positions.add(position); } return positions; - } else if (deviceId == 0) { - return Context.getDeviceManager().getInitialState(getUserId()); - } else { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + } else if (deviceId > 0) { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); if (from != null && to != null) { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return PositionUtil.getPositions(storage, deviceId, from, to); @@ -66,6 +67,17 @@ public class PositionResource extends BaseResource { return storage.getObjects(Position.class, new Request( new Columns.All(), new Condition.LatestPositions(deviceId))); } + } else { + var devices = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, getUserId(), Device.class))); + var deviceIds = devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet()); + + var positions = storage.getObjects(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions())); + return positions.stream() + .filter(position -> deviceIds.contains(position.getDeviceId())) + .collect(Collectors.toList()); } } -- cgit v1.2.3 From 415ba3ddb0f770b829c997beb3e575ffb6e195ec Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Jun 2022 17:06:44 -0700 Subject: Inject connection manager --- schema/changelog-5.1.xml | 4 ++ src/main/java/org/traccar/Context.java | 11 +--- src/main/java/org/traccar/MainEventHandler.java | 8 ++- src/main/java/org/traccar/MainModule.java | 6 -- src/main/java/org/traccar/api/AsyncSocket.java | 8 ++- .../java/org/traccar/api/AsyncSocketServlet.java | 7 +- .../java/org/traccar/database/DeviceManager.java | 11 ++-- .../org/traccar/session/ConnectionManager.java | 76 ++++++++++++++++++---- 8 files changed, 91 insertions(+), 40 deletions(-) (limited to 'src/main/java/org') diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml index d5a8bc1fe..e68325625 100644 --- a/schema/changelog-5.1.xml +++ b/schema/changelog-5.1.xml @@ -12,6 +12,10 @@ + + + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 62ad01c24..a66cde464 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -78,12 +78,6 @@ public final class Context { return deviceManager; } - private static ConnectionManager connectionManager; - - public static ConnectionManager getConnectionManager() { - return connectionManager; - } - private static PermissionsManager permissionsManager; public static PermissionsManager getPermissionsManager() { @@ -114,15 +108,14 @@ public final class Context { if (dataManager != null) { usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); - deviceManager = new DeviceManager(dataManager); + deviceManager = new DeviceManager( + config, dataManager, Main.getInjector().getInstance(ConnectionManager.class)); } identityManager = deviceManager; permissionsManager = new PermissionsManager(dataManager, usersManager); - connectionManager = new ConnectionManager(); - initEventsModule(); } diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index bb84a09d2..d4a0fae6c 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -28,6 +28,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; @@ -44,8 +45,11 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Set connectionlessProtocols = new HashSet<>(); private final Set logAttributes = new LinkedHashSet<>(); + private final ConnectionManager connectionManager; + @Inject - public MainEventHandler() { + public MainEventHandler(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; String connectionlessProtocolList = Context.getConfig().getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); @@ -132,7 +136,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - Context.getConnectionManager().deviceDisconnected(ctx.channel()); + connectionManager.deviceDisconnected(ctx.channel()); } } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 73fe0c460..306bc9e7b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -35,7 +35,6 @@ import org.traccar.database.NotificationManager; import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; -import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; @@ -135,11 +134,6 @@ public class MainModule extends AbstractModule { return Context.getIdentityManager(); } - @Provides - public static ConnectionManager provideConnectionManager() { - return Context.getConnectionManager(); - } - @Provides public static Client provideClient() { return ClientBuilder.newClient().register( diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index 2b866176b..3239d36c4 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -41,10 +41,12 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private static final String KEY_EVENTS = "events"; private final ObjectMapper objectMapper; + private final ConnectionManager connectionManager; private final long userId; - public AsyncSocket(ObjectMapper objectMapper, long userId) { + public AsyncSocket(ObjectMapper objectMapper, ConnectionManager connectionManager, long userId) { this.objectMapper = objectMapper; + this.connectionManager = connectionManager; this.userId = userId; } @@ -56,14 +58,14 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U data.put(KEY_POSITIONS, Context.getDeviceManager().getInitialState(userId)); sendData(data); - Context.getConnectionManager().addListener(userId, this); + connectionManager.addListener(userId, this); } @Override public void onWebSocketClose(int statusCode, String reason) { super.onWebSocketClose(statusCode, reason); - Context.getConnectionManager().removeListener(userId, this); + connectionManager.removeListener(userId, this); } @Override diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 4e55dfebf..317ec469e 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -21,6 +21,7 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.traccar.Context; import org.traccar.api.resource.SessionResource; import org.traccar.config.Keys; +import org.traccar.session.ConnectionManager; import javax.inject.Inject; import javax.servlet.http.HttpSession; @@ -29,10 +30,12 @@ import java.time.Duration; public class AsyncSocketServlet extends JettyWebSocketServlet { private final ObjectMapper objectMapper; + private final ConnectionManager connectionManager; @Inject - public AsyncSocketServlet(ObjectMapper objectMapper) { + public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager) { this.objectMapper = objectMapper; + this.connectionManager = connectionManager; } @Override @@ -41,7 +44,7 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(objectMapper, userId); + return new AsyncSocket(objectMapper, connectionManager, userId); } else { return null; } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 20f179f2e..973cf3f68 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -32,6 +32,7 @@ import org.traccar.Context; import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; @@ -45,6 +46,7 @@ public class DeviceManager extends BaseObjectManager implements Identity private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); private final Config config; + private final ConnectionManager connectionManager; private final long dataRefreshDelay; private Map devicesByUniqueId; @@ -54,9 +56,10 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map deviceStates = new ConcurrentHashMap<>(); - public DeviceManager(DataManager dataManager) { + public DeviceManager(Config config, DataManager dataManager, ConnectionManager connectionManager) { super(dataManager, Device.class); - this.config = Context.getConfig(); + this.config = config; + this.connectionManager = connectionManager; try { writeLock(); if (devicesByUniqueId == null) { @@ -287,9 +290,7 @@ public class DeviceManager extends BaseObjectManager implements Identity positions.put(position.getDeviceId(), position); - if (Context.getConnectionManager() != null) { - Context.getConnectionManager().updatePosition(position); - } + connectionManager.updatePosition(position); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index e01a568aa..ab3c36734 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.Main; import org.traccar.Protocol; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; @@ -30,8 +31,14 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; +import javax.inject.Inject; +import javax.inject.Singleton; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Date; @@ -42,6 +49,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +@Singleton public class ConnectionManager { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); @@ -52,18 +60,23 @@ public class ConnectionManager { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Config config; private final CacheManager cacheManager; + private final Storage storage; + private final Timer timer; 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); - cacheManager = Main.getInjector().getInstance(CacheManager.class); + @Inject + public ConnectionManager( + Config config, CacheManager cacheManager, Storage storage, Timer timer) { + this.config = config; + this.cacheManager = cacheManager; + this.storage = storage; + this.timer = timer; + deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; + updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); } public DeviceSession getDeviceSession(long deviceId) { @@ -91,7 +104,8 @@ public class ConnectionManager { Device device = null; try { for (String uniqueId : uniqueIds) { - device = Context.getIdentityManager().getByUniqueId(uniqueId); + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); if (device != null) { break; } @@ -100,8 +114,8 @@ public class ConnectionManager { LOGGER.warn("Find device error", e); } - if (device == null && Context.getConfig().getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { - device = Context.getIdentityManager().addUnknownDevice(uniqueIds[0]); + if (device == null && config.getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { + device = addUnknownDevice(uniqueIds[0]); } if (device != null && !device.getDisabled()) { @@ -131,6 +145,34 @@ public class ConnectionManager { } } + private Device addUnknownDevice(String uniqueId) { + Device device = new Device(); + device.setName(uniqueId); + device.setUniqueId(uniqueId); + device.setCategory(config.getString(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY)); + + long defaultGroupId = config.getLong(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID); + if (defaultGroupId != 0) { + device.setGroupId(defaultGroupId); + } + + try { + device.setId(storage.addObject(device, new Request(new Columns.Exclude("id")))); + + LOGGER.info("Automatically registered device " + uniqueId); + + if (defaultGroupId != 0) { + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); + Context.getPermissionsManager().refreshAllExtendedPermissions(); + } + + return device; + } catch (StorageException e) { + LOGGER.warn("Automatic device registration error", e); + return null; + } + } + public void deviceDisconnected(Channel channel) { Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); Map endpointSessions = sessionsByEndpoint.remove(endpoint); @@ -156,10 +198,18 @@ public class ConnectionManager { } } - public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getById(deviceId); + public void updateDevice(long deviceId, String status, Date time) { + Device device = cacheManager.getObject(Device.class, deviceId); if (device == null) { - return; + try { + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + } catch (StorageException e) { + LOGGER.warn("Failed to get device", e); + } + if (device == null) { + return; + } } String oldStatus = device.getStatus(); -- cgit v1.2.3 From 0d5c7606c73d84aab44f69936ab62afa0b68939b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Jun 2022 18:50:48 -0700 Subject: Refactor notification manager --- src/main/java/org/traccar/Context.java | 26 ----- src/main/java/org/traccar/MainModule.java | 8 +- .../java/org/traccar/api/BaseObjectResource.java | 10 -- .../traccar/api/resource/NotificationResource.java | 22 +++- .../java/org/traccar/database/DeviceManager.java | 1 - .../traccar/database/ExtendedObjectManager.java | 30 +---- .../org/traccar/database/NotificationManager.java | 126 ++++++++------------- .../org/traccar/database/PermissionsManager.java | 51 --------- .../traccar/handler/events/BaseEventHandler.java | 17 ++- .../org/traccar/notification/EventForwarder.java | 14 +-- .../traccar/notification/NotificatorManager.java | 51 ++++----- .../org/traccar/session/ConnectionManager.java | 9 +- 12 files changed, 116 insertions(+), 249 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index a66cde464..51c420390 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -22,20 +22,14 @@ import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; -import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; -import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.Notification; import org.traccar.model.User; -import org.traccar.notification.EventForwarder; -import org.traccar.notification.NotificatorManager; import org.traccar.session.ConnectionManager; -import org.traccar.session.cache.CacheManager; public final class Context { @@ -84,12 +78,6 @@ public final class Context { return permissionsManager; } - private static NotificationManager notificationManager; - - public static NotificationManager getNotificationManager() { - return notificationManager; - } - public static void init(String configFile) throws Exception { try { @@ -116,18 +104,6 @@ public final class Context { permissionsManager = new PermissionsManager(dataManager, usersManager); - initEventsModule(); - - } - - private static void initEventsModule() { - - notificationManager = new NotificationManager( - dataManager, - Main.getInjector().getInstance(CacheManager.class), - Main.getInjector().getInstance(EventForwarder.class), - Main.getInjector().getInstance(NotificatorManager.class), - Main.getInjector().getInstance(Geocoder.class)); } public static BaseObjectManager getManager(Class clazz) { @@ -137,8 +113,6 @@ public final class Context { return (BaseObjectManager) groupsManager; } else if (clazz.equals(User.class)) { return (BaseObjectManager) usersManager; - } else if (clazz.equals(Notification.class)) { - return (BaseObjectManager) notificationManager; } return null; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 306bc9e7b..dd496e5a4 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -31,7 +31,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; -import org.traccar.database.NotificationManager; import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; @@ -124,11 +123,6 @@ public class MainModule extends AbstractModule { return Context.getUsersManager(); } - @Provides - public static NotificationManager provideNotificationManager() { - return Context.getNotificationManager(); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); @@ -301,7 +295,7 @@ public class MainModule extends AbstractModule { public static EventForwarder provideEventForwarder( Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarder(config, client, cacheManager, usersManager); + return new EventForwarder(config, client, cacheManager); } return null; } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index cc930c591..aa777f3f6 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -22,7 +22,6 @@ import org.traccar.database.ExtendedObjectManager; import org.traccar.database.SimpleObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; @@ -87,7 +86,6 @@ public abstract class BaseObjectResource extends BaseResour ((SimpleObjectManager) manager).refreshUserItems(); } else if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return Response.ok(entity).build(); } @@ -112,7 +110,6 @@ public abstract class BaseObjectResource extends BaseResour if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return Response.ok(entity).build(); } @@ -145,13 +142,6 @@ public abstract class BaseObjectResource extends BaseResour Context.getDeviceManager().updateDeviceCache(true); } Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - if (baseClass.equals(User.class)) { - Context.getPermissionsManager().refreshAllUsersPermissions(); - } else { - Context.getPermissionsManager().refreshAllExtendedPermissions(); - } - } else if (baseClass.equals(Calendar.class)) { - Context.getNotificationManager().refreshItems(); } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 0a95b257a..a42de687d 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -15,7 +15,11 @@ */ package org.traccar.api.resource; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; import javax.inject.Inject; import javax.ws.rs.Consumes; @@ -27,7 +31,8 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.traccar.Context; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Event; import org.traccar.model.Notification; @@ -42,6 +47,8 @@ import org.traccar.storage.StorageException; @Consumes(MediaType.APPLICATION_JSON) public class NotificationResource extends ExtendedObjectResource { + private static final Logger LOGGER = LoggerFactory.getLogger(NotificationResource.class); + @Inject private NotificatorManager notificatorManager; @@ -52,7 +59,18 @@ public class NotificationResource extends ExtendedObjectResource { @GET @Path("types") public Collection get() { - return Context.getNotificationManager().getAllNotificationTypes(); + Set types = new HashSet<>(); + Field[] fields = Event.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { + try { + types.add(new Typed(field.get(null).toString())); + } catch (IllegalArgumentException | IllegalAccessException error) { + LOGGER.warn("Get event types error", error); + } + } + } + return types; } @GET diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 973cf3f68..e1d6ad1dd 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -91,7 +91,6 @@ public class DeviceManager extends BaseObjectManager implements Identity if (defaultGroupId != 0) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return device; diff --git a/src/main/java/org/traccar/database/ExtendedObjectManager.java b/src/main/java/org/traccar/database/ExtendedObjectManager.java index 006ed47b2..fe0ebb96e 100644 --- a/src/main/java/org/traccar/database/ExtendedObjectManager.java +++ b/src/main/java/org/traccar/database/ExtendedObjectManager.java @@ -44,34 +44,6 @@ public abstract class ExtendedObjectManager extends SimpleO refreshExtendedPermissions(); } - public final Set getGroupItems(long groupId) { - try { - readLock(); - Set result = groupItems.get(groupId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - - public final Set getDeviceItems(long deviceId) { - try { - readLock(); - Set result = deviceItems.get(deviceId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - public Set getAllDeviceItems(long deviceId) { try { readLock(); @@ -122,7 +94,7 @@ public abstract class ExtendedObjectManager extends SimpleO .add(devicePermission.getPropertyId()); } - for (Device device : Context.getDeviceManager().getAllDevices()) { + for (Device device : getDataManager().getObjects(Device.class)) { long groupId = device.getGroupId(); while (groupId > 0) { deviceItemsWithGroups diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 3c87aacb2..46b58dd75 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -16,39 +16,36 @@ */ package org.traccar.database; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; import org.traccar.model.Event; import org.traccar.model.Notification; import org.traccar.model.Position; -import org.traccar.model.Typed; -import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.annotation.Nullable; +import javax.inject.Inject; +import java.util.Arrays; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; -public class NotificationManager extends ExtendedObjectManager { +public class NotificationManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); + private final Storage storage; private final CacheManager cacheManager; private final EventForwarder eventForwarder; private final NotificatorManager notificatorManager; @@ -56,81 +53,67 @@ public class NotificationManager extends ExtendedObjectManager { private final boolean geocodeOnRequest; + @Inject public NotificationManager( - DataManager dataManager, CacheManager cacheManager, @Nullable EventForwarder eventForwarder, + Config config, Storage storage, CacheManager cacheManager, @Nullable EventForwarder eventForwarder, NotificatorManager notificatorManager, @Nullable Geocoder geocoder) { - super(dataManager, Notification.class); + this.storage = storage; this.cacheManager = cacheManager; this.eventForwarder = eventForwarder; this.notificatorManager = notificatorManager; this.geocoder = geocoder; - geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); - } - - private Set getEffectiveNotifications(long userId, long deviceId, Date time) { - Set result = new HashSet<>(); - Set deviceNotifications = getAllDeviceItems(deviceId); - for (long itemId : getUserItems(userId)) { - if (getById(itemId).getAlways() || deviceNotifications.contains(itemId)) { - long calendarId = getById(itemId).getCalendarId(); - Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; - if (calendar == null || calendar.checkMoment(time)) { - result.add(itemId); - } - } - } - return result; + geocodeOnRequest = config.getBoolean(Keys.GEOCODER_ON_REQUEST); } public void updateEvent(Event event, Position position) { try { - getDataManager().addObject(event); + event.setId(storage.addObject(event, new Request(new Columns.Exclude("id")))); } catch (StorageException error) { LOGGER.warn("Event save error", error); } - long deviceId = event.getDeviceId(); - Set users = Context.getPermissionsManager().getDeviceUsers(deviceId); - Set usersToForward = new HashSet<>(); - for (long userId : users) { - usersToForward.add(userId); - final Set notificators = new HashSet<>(); - for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { - Notification notification = getById(notificationId); - if (getById(notificationId).getType().equals(event.getType())) { - boolean filter = false; + var notifications = cacheManager.getDeviceObjects(event.getDeviceId(), Notification.class).stream() + .filter(notification -> notification.getType().equals(event.getType())) + .filter(notification -> { if (event.getType().equals(Event.TYPE_ALARM)) { String alarmsAttribute = notification.getString("alarms"); - if (alarmsAttribute == null) { - filter = true; - } else { - List alarms = Arrays.asList(alarmsAttribute.split(",")); - filter = !alarms.contains(event.getString(Position.KEY_ALARM)); + if (alarmsAttribute != null) { + return Arrays.asList(alarmsAttribute.split(",")) + .contains(event.getString(Position.KEY_ALARM)); } + return false; } - if (!filter) { - notificators.addAll(notification.getNotificatorsTypes()); - } - } - } + return true; + }) + .filter(notification -> { + long calendarId = notification.getCalendarId(); + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; + return calendar == null || calendar.checkMoment(event.getEventTime()); + }) + .collect(Collectors.toUnmodifiableList()); + if (!notifications.isEmpty()) { if (position != null && position.getAddress() == null && geocodeOnRequest && geocoder != null) { position.setAddress(geocoder.getAddress(position.getLatitude(), position.getLongitude(), null)); } - User user = Context.getUsersManager().getById(userId); - new Thread(() -> { - for (String notificator : notificators) { - try { - notificatorManager.getNotificator(notificator).send(user, event, position); - } catch (MessageException | InterruptedException exception) { - LOGGER.warn("Notification failed", exception); - } - } - }).start(); + notifications.forEach(notification -> { + cacheManager.getNotificationUsers(notification.getId()).forEach(user -> { + new Thread(() -> { + for (String notificator : notification.getNotificatorsTypes()) { + try { + notificatorManager.getNotificator(notificator).send(user, event, position); + } catch (MessageException | InterruptedException exception) { + LOGGER.warn("Notification failed", exception); + } + } + }).start(); + }); + }); } + if (eventForwarder != null) { - eventForwarder.forwardEvent(event, position, usersToForward); + eventForwarder.forwardEvent(event, position); } } @@ -139,19 +122,4 @@ public class NotificationManager extends ExtendedObjectManager { updateEvent(event.getKey(), event.getValue()); } } - - public Set getAllNotificationTypes() { - Set types = new HashSet<>(); - Field[] fields = Event.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { - try { - types.add(new Typed(field.get(null).toString())); - } catch (IllegalArgumentException | IllegalAccessException error) { - LOGGER.warn("Get event types error", error); - } - } - } - return types; - } } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 3c74c0049..f34810439 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -22,7 +22,6 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.ManagedUser; -import org.traccar.model.Notification; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; @@ -237,31 +236,11 @@ public class PermissionsManager { } } - public void checkDeviceLimit(long userId) throws SecurityException { - int deviceLimit = getUser(userId).getDeviceLimit(); - if (deviceLimit != -1) { - int deviceCount; - if (getUserManager(userId)) { - deviceCount = Context.getDeviceManager().getAllManagedItems(userId).size(); - } else { - deviceCount = Context.getDeviceManager().getAllUserItems(userId).size(); - } - if (deviceCount >= deviceLimit) { - throw new SecurityException("User device limit reached"); - } - } - } - public boolean getUserReadonly(long userId) { User user = getUser(userId); return user != null && user.getReadonly(); } - public boolean getUserLimitCommands(long userId) { - User user = getUser(userId); - return user != null && user.getLimitCommands(); - } - public void checkReadonly(long userId) throws SecurityException { if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { throw new SecurityException("Account is readonly"); @@ -313,18 +292,6 @@ public class PermissionsManager { } } - public void checkGroup(long userId, long groupId) throws SecurityException { - if (!getGroupPermissions(userId).contains(groupId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getUserItems(userId)) { - if (getGroupPermissions(managedUserId).contains(groupId)) { - return; - } - } - throw new SecurityException("Group access denied"); - } - } - public void checkDevice(long userId, long deviceId) throws SecurityException { if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !getUserAdmin(userId)) { checkManager(userId); @@ -354,31 +321,13 @@ public class PermissionsManager { } } - public void refreshAllUsersPermissions() { - if (Context.getNotificationManager() != null) { - Context.getNotificationManager().refreshUserItems(); - } - } - - public void refreshAllExtendedPermissions() { - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) || permission.getPropertyClass().equals(Group.class)) { refreshDeviceAndGroupPermissions(); - refreshAllExtendedPermissions(); } else if (permission.getPropertyClass().equals(ManagedUser.class)) { usersManager.refreshUserItems(); - } else if (permission.getPropertyClass().equals(Notification.class) - && Context.getNotificationManager() != null) { - Context.getNotificationManager().refreshUserItems(); - } - } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { - if (permission.getPropertyClass().equals(Notification.class) - && Context.getNotificationManager() != null) { - Context.getNotificationManager().refreshExtendedPermissions(); } } } diff --git a/src/main/java/org/traccar/handler/events/BaseEventHandler.java b/src/main/java/org/traccar/handler/events/BaseEventHandler.java index 41f677f6c..f7199f6dc 100644 --- a/src/main/java/org/traccar/handler/events/BaseEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BaseEventHandler.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. @@ -18,17 +18,26 @@ package org.traccar.handler.events; import java.util.Map; import org.traccar.BaseDataHandler; -import org.traccar.Context; +import org.traccar.database.NotificationManager; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + public abstract class BaseEventHandler extends BaseDataHandler { + private NotificationManager notificationManager; + + @Inject + public void setNotificationManager(NotificationManager notificationManager) { + this.notificationManager = notificationManager; + } + @Override protected Position handlePosition(Position position) { Map events = analyzePosition(position); - if (events != null && Context.getNotificationManager() != null) { - Context.getNotificationManager().updateEvents(events); + if (events != null) { + notificationManager.updateEvents(events); } return position; } diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index 5afff1b7b..279d5e678 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -19,7 +19,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.UsersManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -33,7 +32,6 @@ import javax.ws.rs.client.Invocation; import javax.ws.rs.client.InvocationCallback; import java.util.HashMap; import java.util.Map; -import java.util.Set; public class EventForwarder { @@ -44,12 +42,10 @@ public class EventForwarder { private final Client client; private final CacheManager cacheManager; - private final UsersManager usersManager; - public EventForwarder(Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { + public EventForwarder(Config config, Client client, CacheManager cacheManager) { this.client = client; this.cacheManager = cacheManager; - this.usersManager = usersManager; url = config.getString(Keys.EVENT_FORWARD_URL); header = config.getString(Keys.EVENT_FORWARD_HEADERS); } @@ -59,9 +55,8 @@ public class EventForwarder { private static final String KEY_GEOFENCE = "geofence"; private static final String KEY_DEVICE = "device"; private static final String KEY_MAINTENANCE = "maintenance"; - private static final String KEY_USERS = "users"; - public final void forwardEvent(Event event, Position position, Set users) { + public final void forwardEvent(Event event, Position position) { Invocation.Builder requestBuilder = client.target(url).request(); @@ -74,7 +69,7 @@ public class EventForwarder { LOGGER.debug("Event forwarding initiated"); requestBuilder.async().post( - Entity.json(preparePayload(event, position, users)), new InvocationCallback() { + Entity.json(preparePayload(event, position)), new InvocationCallback() { @Override public void completed(Object o) { LOGGER.debug("Event forwarding succeeded"); @@ -87,7 +82,7 @@ public class EventForwarder { }); } - protected Map preparePayload(Event event, Position position, Set users) { + protected Map preparePayload(Event event, Position position) { Map data = new HashMap<>(); data.put(KEY_EVENT, event); if (position != null) { @@ -109,7 +104,6 @@ public class EventForwarder { data.put(KEY_MAINTENANCE, maintenance); } } - data.put(KEY_USERS, usersManager.getItems(users)); return data; } diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index d6ebb2c4a..1d9f4f423 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -16,29 +16,29 @@ */ package org.traccar.notification; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - +import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Typed; +import org.traccar.notificators.Notificator; import org.traccar.notificators.NotificatorFirebase; import org.traccar.notificators.NotificatorMail; import org.traccar.notificators.NotificatorNull; -import org.traccar.notificators.Notificator; +import org.traccar.notificators.NotificatorPushover; import org.traccar.notificators.NotificatorSms; +import org.traccar.notificators.NotificatorTelegram; import org.traccar.notificators.NotificatorTraccar; import org.traccar.notificators.NotificatorWeb; -import org.traccar.notificators.NotificatorTelegram; -import org.traccar.notificators.NotificatorPushover; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; @Singleton public class NotificatorManager { @@ -54,36 +54,33 @@ public class NotificatorManager { "telegram", NotificatorTelegram.class, "pushover", NotificatorPushover.class); - private final Map notificators = new HashMap<>(); + private final Injector injector; + + private final Set types = new HashSet<>(); @Inject - public NotificatorManager(Config config) { + public NotificatorManager(Injector injector, Config config) { + this.injector = injector; String types = config.getString(Keys.NOTIFICATOR_TYPES); if (types != null) { - for (String type : types.split(",")) { - var notificatorClass = NOTIFICATORS_ALL.get(type); - if (notificatorClass != null) { - notificators.put(type, Main.getInjector().getInstance(notificatorClass)); - } - } + this.types.addAll(Arrays.asList(types.split(","))); } } public Notificator getNotificator(String type) { - final Notificator notificator = notificators.get(type); - if (notificator == null) { - LOGGER.warn("No notificator configured for type : " + type); - return new NotificatorNull(); + var clazz = NOTIFICATORS_ALL.get(type); + if (clazz != null) { + var notificator = injector.getInstance(clazz); + if (notificator != null) { + return notificator; + } } - return notificator; + LOGGER.warn("Failed to get notificator {}", type); + return new NotificatorNull(); } public Set getAllNotificatorTypes() { - Set result = new HashSet<>(); - for (String notificator : notificators.keySet()) { - result.add(new Typed(notificator)); - } - return result; + return types.stream().map(Typed::new).collect(Collectors.toUnmodifiableSet()); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index ab3c36734..dc714379b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -25,6 +25,7 @@ import org.traccar.Main; import org.traccar.Protocol; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.model.Device; @@ -63,6 +64,7 @@ public class ConnectionManager { private final Config config; private final CacheManager cacheManager; private final Storage storage; + private final NotificationManager notificationManager; private final Timer timer; private final Map> listeners = new ConcurrentHashMap<>(); @@ -70,10 +72,12 @@ public class ConnectionManager { @Inject public ConnectionManager( - Config config, CacheManager cacheManager, Storage storage, Timer timer) { + Config config, CacheManager cacheManager, Storage storage, + NotificationManager notificationManager, Timer timer) { this.config = config; this.cacheManager = cacheManager; this.storage = storage; + this.notificationManager = notificationManager; this.timer = timer; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); @@ -163,7 +167,6 @@ public class ConnectionManager { if (defaultGroupId != 0) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return device; @@ -236,7 +239,7 @@ public class ConnectionManager { break; } events.put(new Event(eventType, deviceId), null); - Context.getNotificationManager().updateEvents(events); + notificationManager.updateEvents(events); } Timeout timeout = timeouts.remove(deviceId); -- cgit v1.2.3 From 63ecf80c11ec9bce19df18fc24ad863a9c2cb212 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 15 Jun 2022 09:55:50 -0700 Subject: Remove users manager --- schema/changelog-5.1.xml | 12 +++ src/main/java/org/traccar/Context.java | 13 +-- src/main/java/org/traccar/MainModule.java | 9 +- .../java/org/traccar/api/BaseObjectResource.java | 17 ++-- .../org/traccar/api/resource/DeviceResource.java | 16 ++-- .../org/traccar/api/resource/PasswordResource.java | 43 +++++----- .../org/traccar/api/resource/SessionResource.java | 6 +- .../org/traccar/api/resource/UserResource.java | 77 ++++++++++------- .../traccar/api/security/PermissionsService.java | 33 +++++++- .../java/org/traccar/database/DataManager.java | 3 +- .../java/org/traccar/database/DeviceManager.java | 16 ---- .../org/traccar/database/PermissionsManager.java | 98 ++++----------------- .../org/traccar/database/SimpleObjectManager.java | 70 --------------- .../java/org/traccar/database/UsersManager.java | 99 ---------------------- 14 files changed, 153 insertions(+), 359 deletions(-) delete mode 100644 src/main/java/org/traccar/database/UsersManager.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml index e68325625..e972813f6 100644 --- a/schema/changelog-5.1.xml +++ b/schema/changelog-5.1.xml @@ -16,6 +16,18 @@ + + + + + + + + + + + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 51c420390..5eaa1e15c 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -23,12 +23,10 @@ import org.traccar.database.DeviceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.PermissionsManager; -import org.traccar.database.UsersManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.User; import org.traccar.session.ConnectionManager; public final class Context { @@ -54,12 +52,6 @@ public final class Context { return dataManager; } - private static UsersManager usersManager; - - public static UsersManager getUsersManager() { - return usersManager; - } - private static GroupsManager groupsManager; public static GroupsManager getGroupsManager() { @@ -94,7 +86,6 @@ public final class Context { } if (dataManager != null) { - usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); deviceManager = new DeviceManager( config, dataManager, Main.getInjector().getInstance(ConnectionManager.class)); @@ -102,7 +93,7 @@ public final class Context { identityManager = deviceManager; - permissionsManager = new PermissionsManager(dataManager, usersManager); + permissionsManager = new PermissionsManager(dataManager, dataManager.getStorage()); } @@ -111,8 +102,6 @@ public final class Context { return (BaseObjectManager) deviceManager; } else if (clazz.equals(Group.class)) { return (BaseObjectManager) groupsManager; - } else if (clazz.equals(User.class)) { - return (BaseObjectManager) usersManager; } return null; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index dd496e5a4..dd7e375d3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -31,7 +31,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; -import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.database.DataManager; @@ -118,11 +117,6 @@ public class MainModule extends AbstractModule { return Context.getDataManager(); } - @Provides - public static UsersManager provideUsersManager() { - return Context.getUsersManager(); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); @@ -292,8 +286,7 @@ public class MainModule extends AbstractModule { } @Provides - public static EventForwarder provideEventForwarder( - Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { + public static EventForwarder provideEventForwarder(Config config, Client client, CacheManager cacheManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { return new EventForwarder(config, client, cacheManager); } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index aa777f3f6..f8545a5d7 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -19,7 +19,6 @@ package org.traccar.api; import org.traccar.Context; import org.traccar.database.BaseObjectManager; import org.traccar.database.ExtendedObjectManager; -import org.traccar.database.SimpleObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -82,9 +81,7 @@ public abstract class BaseObjectResource extends BaseResour cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager) manager).refreshUserItems(); - } else if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { + if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); } return Response.ok(entity).build(); @@ -95,6 +92,11 @@ public abstract class BaseObjectResource extends BaseResour public Response update(T entity) throws StorageException { permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); + if (entity instanceof User) { + User before = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + permissionsService.checkUserUpdate(getUserId(), before, (User) entity); + } BaseObjectManager manager = Context.getManager(baseClass); if (manager != null) { @@ -123,11 +125,8 @@ public abstract class BaseObjectResource extends BaseResour BaseObjectManager manager = Context.getManager(baseClass); if (manager != null) { manager.removeItem(id); - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager) manager).refreshUserItems(); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager) manager).refreshExtendedPermissions(); - } + if (manager instanceof ExtendedObjectManager) { + ((ExtendedObjectManager) manager).refreshExtendedPermissions(); } } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 309308e75..cd5ebf0c5 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -49,7 +49,7 @@ public class DeviceResource extends BaseObjectResource { public Collection get( @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("uniqueId") List uniqueIds, - @QueryParam("id") List deviceIds) { + @QueryParam("id") List deviceIds) throws StorageException { DeviceManager deviceManager = Context.getDeviceManager(); Set result; if (all) { @@ -57,13 +57,13 @@ public class DeviceResource extends BaseObjectResource { result = deviceManager.getAllItems(); } else { Context.getPermissionsManager().checkManager(getUserId()); - result = deviceManager.getManagedItems(getUserId()); + result = deviceManager.getUserItems(getUserId()); } } else if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { if (userId == 0) { userId = getUserId(); } - Context.getPermissionsManager().checkUser(getUserId(), userId); + permissionsService.checkUser(getUserId(), userId); if (Context.getPermissionsManager().getUserAdmin(getUserId())) { result = deviceManager.getAllUserItems(userId); } else { @@ -73,11 +73,11 @@ public class DeviceResource extends BaseObjectResource { result = new HashSet<>(); for (String uniqueId : uniqueIds) { Device device = deviceManager.getByUniqueId(uniqueId); - Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); + permissionsService.checkPermission(Device.class, getUserId(), device.getId()); result.add(device.getId()); } for (Long deviceId : deviceIds) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + permissionsService.checkPermission(Device.class, getUserId(), deviceId); result.add(deviceId); } } @@ -87,9 +87,9 @@ public class DeviceResource extends BaseObjectResource { @Path("{id}/accumulators") @PUT public Response updateAccumulators(DeviceAccumulators entity) throws StorageException { - if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { - Context.getPermissionsManager().checkManager(getUserId()); - Context.getPermissionsManager().checkPermission(Device.class, getUserId(), entity.getDeviceId()); + if (permissionsService.notAdmin(getUserId())) { + permissionsService.checkManager(getUserId()); + permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); } Context.getDeviceManager().resetDeviceAccumulators(entity); LogAction.resetDeviceAccumulators(getUserId(), entity.getDeviceId()); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index c7244f41c..643471797 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -15,12 +15,14 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.model.User; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; import javax.inject.Inject; @@ -51,18 +53,17 @@ public class PasswordResource extends BaseResource { @PermitAll @POST public Response reset(@FormParam("email") String email) throws StorageException, MessagingException { - for (long userId : Context.getUsersManager().getAllItems()) { - User user = Context.getUsersManager().getById(userId); - if (email.equals(user.getEmail())) { - String token = UUID.randomUUID().toString().replaceAll("-", ""); - user.set(PASSWORD_RESET_TOKEN, token); - Context.getUsersManager().updateItem(user); - var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", token); - var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); - break; - } + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("email", "email", email))); + if (user != null) { + String token = UUID.randomUUID().toString().replaceAll("-", ""); + user.set(PASSWORD_RESET_TOKEN, token); + storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + + var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); + velocityContext.put("token", token); + var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); + mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } return Response.ok().build(); } @@ -72,14 +73,14 @@ public class PasswordResource extends BaseResource { @POST public Response update( @FormParam("token") String token, @FormParam("password") String password) throws StorageException { - for (long userId : Context.getUsersManager().getAllItems()) { - User user = Context.getUsersManager().getById(userId); - if (token.equals(user.getString(PASSWORD_RESET_TOKEN))) { - user.getAttributes().remove(PASSWORD_RESET_TOKEN); - user.setPassword(password); - Context.getUsersManager().updateItem(user); - return Response.ok().build(); - } + User user = storage.getObjects(User.class, new Request(new Columns.All())).stream() + .filter(it -> token.equals(it.getString(PASSWORD_RESET_TOKEN))) + .findFirst().orElse(null); + if (user != null) { + user.getAttributes().remove(PASSWORD_RESET_TOKEN); + user.setPassword(password); + storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 1ccba1270..a0bf0cba5 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -22,6 +22,9 @@ import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; import javax.servlet.http.Cookie; @@ -59,7 +62,8 @@ public class SessionResource extends BaseResource { public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException { if (token != null) { - User user = Context.getUsersManager().getUserByToken(token); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("token", "token", token))); if (user != null) { Context.getPermissionsManager().checkUserEnabled(user.getId()); request.getSession().setAttribute(USER_ID_KEY, user.getId()); diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 84f41ca1a..20fce9e32 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 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. @@ -15,17 +15,20 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseObjectResource; +import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.UsersManager; import org.traccar.helper.LogAction; import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -34,63 +37,77 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.sql.SQLException; import java.util.Collection; import java.util.Date; -import java.util.Set; @Path("users") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class UserResource extends BaseObjectResource { + @Inject + private Config config; + public UserResource() { super(User.class); } @GET - public Collection get(@QueryParam("userId") long userId) throws SQLException { - UsersManager usersManager = Context.getUsersManager(); - Set result; - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - if (userId != 0) { - result = usersManager.getUserItems(userId); - } else { - result = usersManager.getAllItems(); - } - } else if (Context.getPermissionsManager().getUserManager(getUserId())) { - result = usersManager.getManagedItems(getUserId()); + public Collection get(@QueryParam("userId") long userId) throws StorageException { + permissionsService.checkUser(getUserId(), userId); + if (userId > 0) { + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); + } else if (permissionsService.notAdmin(getUserId())) { + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())); } else { - throw new SecurityException("Admin or manager access required"); + return storage.getObjects(baseClass, new Request(new Columns.All())); } - return usersManager.getItems(result); } @Override @PermitAll @POST public Response add(User entity) throws StorageException { - if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { - Context.getPermissionsManager().checkUserUpdate(getUserId(), new User(), entity); - if (Context.getPermissionsManager().getUserManager(getUserId())) { - Context.getPermissionsManager().checkUserLimit(getUserId()); + User currentUser = permissionsService.getUser(getUserId()); + if (permissionsService.notAdmin(getUserId())) { + permissionsService.checkUserUpdate(getUserId(), new User(), entity); + if (currentUser != null && currentUser.getUserLimit() != 0) { + int userLimit = currentUser.getUserLimit(); + if (userLimit > 0) { + int userCount = storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())) + .size(); + if (userCount >= userLimit) { + throw new SecurityException("Manager user limit reached"); + } + } } else { - Context.getPermissionsManager().checkRegistration(getUserId()); - entity.setDeviceLimit(Context.getConfig().getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); - int expirationDays = Context.getConfig().getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); + if (!permissionsService.getServer().getRegistration()) { + throw new SecurityException("Registration disabled"); + } + entity.setDeviceLimit(config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); + int expirationDays = config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); if (expirationDays > 0) { - entity.setExpirationTime( - new Date(System.currentTimeMillis() + (long) expirationDays * 24 * 3600 * 1000)); + entity.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); } } } - Context.getUsersManager().addItem(entity); + + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + LogAction.create(getUserId(), entity); - if (Context.getPermissionsManager().getUserManager(getUserId())) { + + if (currentUser != null && currentUser.getUserLimit() != 0) { storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); } - Context.getUsersManager().refreshUserItems(); return Response.ok(entity).build(); } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index c70414b2a..f39ded2b7 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -57,7 +57,7 @@ public class PermissionsService { } public User getUser(long userId) throws StorageException { - if (user == null) { + if (user == null && userId > 0) { user = storage.getObject( User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); } @@ -74,6 +74,12 @@ public class PermissionsService { } } + public void checkManager(long userId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator() && getUser(userId).getUserLimit() == 0) { + throw new SecurityException("Manager access required"); + } + } + public interface CheckRestrictionCallback { boolean denied(UserRestrictions userRestrictions); } @@ -137,6 +143,31 @@ public class PermissionsService { } } + public void checkUserUpdate(long userId, User before, User after) throws StorageException, SecurityException { + if (before.getAdministrator() != after.getAdministrator() + || before.getDeviceLimit() != after.getDeviceLimit() + || before.getUserLimit() != after.getUserLimit()) { + checkAdmin(userId); + } + User user = getUser(userId); + if (user != null && user.getExpirationTime() != null + && (after.getExpirationTime() == null + || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { + checkAdmin(userId); + } + if (before.getReadonly() != after.getReadonly() + || before.getDeviceReadonly() != after.getDeviceReadonly() + || before.getDisabled() != after.getDisabled() + || before.getLimitCommands() != after.getLimitCommands() + || before.getDisableReports() != after.getDisableReports()) { + if (userId == after.getId()) { + checkAdmin(userId); + } else { + checkUser(userId, after.getId()); + } + } + } + public void checkPermission( Class clazz, long userId, long objectId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index fd45a0321..6921634dd 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -25,7 +25,6 @@ import liquibase.database.DatabaseFactory; import liquibase.exception.LiquibaseException; import liquibase.resource.FileSystemResourceAccessor; import liquibase.resource.ResourceAccessor; -import org.traccar.Context; import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -155,7 +154,7 @@ public class DataManager { } else { if (ldapProvider != null && ldapProvider.login(email, password)) { user = ldapProvider.getUser(email); - Context.getUsersManager().addItem(user); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); return user; } } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index e1d6ad1dd..9ba486988 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -177,22 +177,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - public Set getAllManagedItems(long userId) { - Set result = new HashSet<>(getAllUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getAllUserItems(managedUserId)); - } - return result; - } - - public Set getManagedItems(long userId) { - Set result = new HashSet<>(getUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - private void addByUniqueId(Device device) { try { writeLock(); diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index f34810439..833480eea 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -18,14 +18,17 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.model.BaseModel; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import java.util.HashMap; import java.util.HashSet; @@ -39,7 +42,7 @@ public class PermissionsManager { private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class); private final DataManager dataManager; - private final UsersManager usersManager; + private final Storage storage; private volatile Server server; @@ -50,9 +53,9 @@ public class PermissionsManager { private final Map> deviceUsers = new HashMap<>(); private final Map> groupDevices = new HashMap<>(); - public PermissionsManager(DataManager dataManager, UsersManager usersManager) { + public PermissionsManager(DataManager dataManager, Storage storage) { this.dataManager = dataManager; - this.usersManager = usersManager; + this.storage = storage; refreshServer(); refreshDeviceAndGroupPermissions(); } @@ -74,11 +77,11 @@ public class PermissionsManager { } public User getUser(long userId) { - readLock(); try { - return usersManager.getById(userId); - } finally { - readUnlock(); + return storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", userId))); + } catch (StorageException e) { + throw new RuntimeException(e); } } @@ -222,20 +225,6 @@ public class PermissionsManager { } } - public void checkManager(long userId, long managedUserId) throws SecurityException { - checkManager(userId); - if (!usersManager.getUserItems(userId).contains(managedUserId)) { - throw new SecurityException("User access denied"); - } - } - - public void checkUserLimit(long userId) throws SecurityException { - int userLimit = getUser(userId).getUserLimit(); - if (userLimit != -1 && usersManager.getUserItems(userId).size() >= userLimit) { - throw new SecurityException("Manager user limit reached"); - } - } - public boolean getUserReadonly(long userId) { User user = getUser(userId); return user != null && user.getReadonly(); @@ -260,64 +249,11 @@ public class PermissionsManager { } } - public void checkUserUpdate(long userId, User before, User after) throws SecurityException { - if (before.getAdministrator() != after.getAdministrator() - || before.getDeviceLimit() != after.getDeviceLimit() - || before.getUserLimit() != after.getUserLimit()) { - checkAdmin(userId); - } - User user = getUser(userId); - if (user != null && user.getExpirationTime() != null - && (after.getExpirationTime() == null - || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { - checkAdmin(userId); - } - if (before.getReadonly() != after.getReadonly() - || before.getDeviceReadonly() != after.getDeviceReadonly() - || before.getDisabled() != after.getDisabled() - || before.getLimitCommands() != after.getLimitCommands() - || before.getDisableReports() != after.getDisableReports()) { - if (userId == after.getId()) { - checkAdmin(userId); - } - if (!getUserAdmin(userId)) { - checkManager(userId); - } - } - } - - public void checkUser(long userId, long managedUserId) throws SecurityException { - if (userId != managedUserId && !getUserAdmin(userId)) { - checkManager(userId, managedUserId); - } - } - public void checkDevice(long userId, long deviceId) throws SecurityException { - if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getUserItems(userId)) { - if (Context.getDeviceManager().getUserItems(managedUserId).contains(deviceId)) { - return; - } - } - throw new SecurityException("Device access denied"); - } - } - - public void checkRegistration(long userId) { - if (!server.getRegistration() && !getUserAdmin(userId)) { - throw new SecurityException("Registration disabled"); - } - } - - public void checkPermission(Class object, long userId, long objectId) - throws SecurityException { - SimpleObjectManager manager = null; - - if (object.equals(Device.class)) { - checkDevice(userId, objectId); - } else { - throw new IllegalArgumentException("Unknown object type"); + try { + new PermissionsService(storage).checkPermission(Device.class, userId, deviceId); + } catch (StorageException e) { + throw new RuntimeException(e); } } @@ -326,8 +262,6 @@ public class PermissionsManager { if (permission.getPropertyClass().equals(Device.class) || permission.getPropertyClass().equals(Group.class)) { refreshDeviceAndGroupPermissions(); - } else if (permission.getPropertyClass().equals(ManagedUser.class)) { - usersManager.refreshUserItems(); } } } diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java index 74bbc054f..8bb22b8a8 100644 --- a/src/main/java/org/traccar/database/SimpleObjectManager.java +++ b/src/main/java/org/traccar/database/SimpleObjectManager.java @@ -16,82 +16,12 @@ */ package org.traccar.database; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.model.BaseModel; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; public abstract class SimpleObjectManager extends BaseObjectManager { - private static final Logger LOGGER = LoggerFactory.getLogger(SimpleObjectManager.class); - - private Map> userItems; - protected SimpleObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); } - public final Set getUserItems(long userId) { - try { - readLock(); - Set result = userItems.get(userId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - - public Set getManagedItems(long userId) { - Set result = getUserItems(userId); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - - public final boolean checkItemPermission(long userId, long itemId) { - return getUserItems(userId).contains(itemId); - } - - @Override - public void refreshItems() { - super.refreshItems(); - refreshUserItems(); - } - - public final void refreshUserItems() { - if (getDataManager() != null) { - try { - writeLock(); - userItems = new ConcurrentHashMap<>(); - for (Permission permission : getDataManager().getPermissions(User.class, getBaseClass())) { - Set items = userItems.computeIfAbsent(permission.getOwnerId(), key -> new HashSet<>()); - items.add(permission.getPropertyId()); - } - } catch (StorageException | ClassNotFoundException error) { - LOGGER.warn("Error getting permissions", error); - } finally { - writeUnlock(); - } - } - } - - @Override - public void removeItem(long itemId) throws StorageException { - super.removeItem(itemId); - refreshUserItems(); - } - } diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java deleted file mode 100644 index a54226cfe..000000000 --- a/src/main/java/org/traccar/database/UsersManager.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.database; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.traccar.model.User; -import org.traccar.storage.StorageException; - -public class UsersManager extends SimpleObjectManager { - - private Map usersTokens; - - public UsersManager(DataManager dataManager) { - super(dataManager, User.class); - if (usersTokens == null) { - usersTokens = new ConcurrentHashMap<>(); - } - } - - private void putToken(User user) { - if (usersTokens == null) { - usersTokens = new ConcurrentHashMap<>(); - } - if (user.getToken() != null) { - usersTokens.put(user.getToken(), user); - } - } - - @Override - protected void addNewItem(User user) { - super.addNewItem(user); - putToken(user); - } - - @Override - protected void updateCachedItem(User user) { - User cachedUser = getById(user.getId()); - super.updateCachedItem(user); - putToken(user); - if (cachedUser.getToken() != null && !cachedUser.getToken().equals(user.getToken())) { - usersTokens.remove(cachedUser.getToken()); - } - } - - @Override - public void addItem(User user) throws StorageException { - super.addItem(user); - getDataManager().updateUserPassword(user); - } - - @Override - public void updateItem(User user) throws StorageException { - if (user.getHashedPassword() != null) { - getDataManager().updateUserPassword(user); - } - super.updateItem(user); - } - - @Override - protected void removeCachedItem(long userId) { - User cachedUser = getById(userId); - if (cachedUser != null) { - String userToken = cachedUser.getToken(); - super.removeCachedItem(userId); - if (userToken != null) { - usersTokens.remove(userToken); - } - } - } - - @Override - public Set getManagedItems(long userId) { - Set result = getUserItems(userId); - result.add(userId); - return result; - } - - public User getUserByToken(String token) { - return usersTokens.get(token); - } - -} -- cgit v1.2.3 From ca884b765f3f7a642c435be886dbec40f9d1f661 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 15 Jun 2022 19:08:58 -0700 Subject: Convert some config usages --- src/main/java/org/traccar/BasePipelineFactory.java | 7 ++++--- src/main/java/org/traccar/BaseProtocolDecoder.java | 24 +++------------------- .../java/org/traccar/ExtendedObjectDecoder.java | 22 +++++++++++++++++++- src/main/java/org/traccar/MainEventHandler.java | 8 ++++---- src/main/java/org/traccar/ServerManager.java | 6 ++++-- src/main/java/org/traccar/TrackerClient.java | 15 +++++++------- src/main/java/org/traccar/TrackerServer.java | 12 ++++++----- .../traccar/api/resource/AttributeResource.java | 7 ++++++- .../java/org/traccar/handler/GeocoderHandler.java | 3 +-- src/main/java/org/traccar/handler/TimeHandler.java | 3 +-- 10 files changed, 59 insertions(+), 48 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 1f383f211..3eb7011a1 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -22,6 +22,7 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOutboundHandler; import io.netty.channel.ChannelPipeline; import io.netty.handler.timeout.IdleStateHandler; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.handler.ComputedAttributesHandler; import org.traccar.handler.CopyAttributesHandler; @@ -58,12 +59,12 @@ public abstract class BasePipelineFactory extends ChannelInitializer { private final String protocol; private int timeout; - public BasePipelineFactory(TrackerConnector connector, String protocol) { + public BasePipelineFactory(TrackerConnector connector, Config config, String protocol) { this.connector = connector; this.protocol = protocol; - timeout = Context.getConfig().getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); + timeout = config.getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); if (timeout == 0) { - timeout = Context.getConfig().getInteger(Keys.SERVER_TIMEOUT); + timeout = config.getInteger(Keys.SERVER_TIMEOUT); } } diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 5b3f129de..cbcb429b3 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; import org.traccar.database.IdentityManager; @@ -46,7 +45,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final Protocol protocol; - private Config config; private IdentityManager identityManager; private ConnectionManager connectionManager; private StatisticsManager statisticsManager; @@ -57,22 +55,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.protocol = protocol; } - /** - * Method called when config is initialized. - */ - protected void init() { - } - - public Config getConfig() { - return config; - } - - @Inject - public void setConfig(Config config) { - this.config = config; - init(); - } - public IdentityManager getIdentityManager() { return identityManager; } @@ -115,7 +97,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } public String getServer(Channel channel, char delimiter) { - String server = config.getString(Keys.PROTOCOL_SERVER.withPrefix(getProtocolName())); + String server = getConfig().getString(Keys.PROTOCOL_SERVER.withPrefix(getProtocolName())); if (server == null && channel != null) { InetSocketAddress address = (InetSocketAddress) channel.localAddress(); server = address.getAddress().getHostAddress() + ":" + address.getPort(); @@ -124,7 +106,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } protected double convertSpeed(double value, String defaultUnits) { - switch (config.getString(getProtocolName() + ".speed", defaultUnits)) { + switch (getConfig().getString(getProtocolName() + ".speed", defaultUnits)) { case "kmh": return UnitsConverter.knotsFromKph(value); case "mps": @@ -222,7 +204,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { @Override protected Object handleEmptyMessage(Channel channel, SocketAddress remoteAddress, Object msg) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (config.getBoolean(Keys.DATABASE_SAVE_EMPTY) && deviceSession != null) { + if (getConfig().getBoolean(Keys.DATABASE_SAVE_EMPTY) && deviceSession != null) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); diff --git a/src/main/java/org/traccar/ExtendedObjectDecoder.java b/src/main/java/org/traccar/ExtendedObjectDecoder.java index 46720da52..f79a36c85 100644 --- a/src/main/java/org/traccar/ExtendedObjectDecoder.java +++ b/src/main/java/org/traccar/ExtendedObjectDecoder.java @@ -21,18 +21,38 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; import org.traccar.model.Position; +import javax.inject.Inject; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter { + private Config config; + + public Config getConfig() { + return config; + } + + @Inject + public void setConfig(Config config) { + this.config = config; + init(); + } + + /** + * Method called when config is initialized. + */ + protected void init() { + } + private void saveOriginal(Object decodedMessage, Object originalMessage) { - if (Context.getConfig().getBoolean(Keys.DATABASE_SAVE_ORIGINAL) && decodedMessage instanceof Position) { + if (getConfig().getBoolean(Keys.DATABASE_SAVE_ORIGINAL) && decodedMessage instanceof Position) { Position position = (Position) decodedMessage; if (originalMessage instanceof ByteBuf) { ByteBuf buf = (ByteBuf) originalMessage; diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index d4a0fae6c..7fff2e13f 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; @@ -48,14 +49,13 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final ConnectionManager connectionManager; @Inject - public MainEventHandler(ConnectionManager connectionManager) { + public MainEventHandler(Config config, ConnectionManager connectionManager) { this.connectionManager = connectionManager; - String connectionlessProtocolList = Context.getConfig().getString(Keys.STATUS_IGNORE_OFFLINE); + String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); } - logAttributes.addAll(Arrays.asList( - Context.getConfig().getString(Keys.LOGGER_ATTRIBUTES).split("[, ]"))); + logAttributes.addAll(Arrays.asList(config.getString(Keys.LOGGER_ATTRIBUTES).split("[, ]"))); } @Override diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index f4f6e1ba4..ffb15d8ca 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -18,6 +18,7 @@ package org.traccar; 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.helper.ClassScanner; @@ -41,9 +42,10 @@ public class ServerManager implements LifecycleObject { private final Map protocolList = new ConcurrentHashMap<>(); @Inject - public ServerManager(Injector injector) throws IOException, URISyntaxException, ReflectiveOperationException { + public ServerManager( + Injector injector, Config config) throws IOException, URISyntaxException, ReflectiveOperationException { for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { - if (Context.getConfig().hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { + if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); injector.injectMembers(protocol); connectorList.addAll(protocol.getConnectorList()); diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index 12971849c..5a3c38212 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -54,14 +54,15 @@ public abstract class TrackerClient implements TrackerConnector { } public TrackerClient(String protocol) { + Config config = Context.getConfig(); - secure = Context.getConfig().getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); - interval = Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); - address = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); - port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol), secure ? 443 : 80); - devices = Context.getConfig().getString(Keys.PROTOCOL_DEVICES.withPrefix(protocol)).split("[, ]"); + secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); + interval = config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); + address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); + port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol), secure ? 443 : 80); + devices = config.getString(Keys.PROTOCOL_DEVICES.withPrefix(protocol)).split("[, ]"); - BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { + BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, config, protocol) { @Override protected void addTransportHandlers(PipelineBuilder pipeline) { try { @@ -78,7 +79,7 @@ public abstract class TrackerClient implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { try { - TrackerClient.this.addProtocolHandlers(pipeline, Context.getConfig()); + TrackerClient.this.addProtocolHandlers(pipeline, config); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index b279d3479..dd83ca6b0 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -58,11 +58,13 @@ public abstract class TrackerServer implements TrackerConnector { public TrackerServer(boolean datagram, String protocol) { this.datagram = datagram; - secure = Context.getConfig().getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); - address = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); - port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); + Config config = Context.getConfig(); - BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { + secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); + address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); + port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); + + BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, config, protocol) { @Override protected void addTransportHandlers(PipelineBuilder pipeline) { try { @@ -77,7 +79,7 @@ public abstract class TrackerServer implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - TrackerServer.this.addProtocolHandlers(pipeline, Context.getConfig()); + TrackerServer.this.addProtocolHandlers(pipeline, config); } }; diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index ab7e43add..43d8a7ccd 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -16,6 +16,7 @@ */ package org.traccar.api.resource; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.POST; @@ -29,6 +30,7 @@ import javax.ws.rs.core.Response; import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; +import org.traccar.config.Config; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; @@ -43,6 +45,9 @@ import org.traccar.storage.query.Request; @Consumes(MediaType.APPLICATION_JSON) public class AttributeResource extends ExtendedObjectResource { + @Inject + private Config config; + public AttributeResource() { super(Attribute.class); } @@ -57,7 +62,7 @@ public class AttributeResource extends ExtendedObjectResource { new Columns.All(), new Condition.LatestPositions(deviceId))); - Object result = new ComputedAttributesHandler(Context.getConfig(), Context.getIdentityManager(), null) + Object result = new ComputedAttributesHandler(config, Context.getIdentityManager(), null) .computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { diff --git a/src/main/java/org/traccar/handler/GeocoderHandler.java b/src/main/java/org/traccar/handler/GeocoderHandler.java index 614cf97d6..075bdf815 100644 --- a/src/main/java/org/traccar/handler/GeocoderHandler.java +++ b/src/main/java/org/traccar/handler/GeocoderHandler.java @@ -20,7 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.IdentityManager; @@ -42,7 +41,7 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { Config config, Geocoder geocoder, IdentityManager identityManager) { this.geocoder = geocoder; this.identityManager = identityManager; - ignorePositions = Context.getConfig().getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); + ignorePositions = config.getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); } diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java index c7e5e6e5c..439c076c7 100644 --- a/src/main/java/org/traccar/handler/TimeHandler.java +++ b/src/main/java/org/traccar/handler/TimeHandler.java @@ -19,7 +19,6 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; @@ -44,7 +43,7 @@ public class TimeHandler extends ChannelInboundHandlerAdapter { } else { useServerTime = false; } - String protocolList = Context.getConfig().getString(Keys.TIME_PROTOCOLS); + String protocolList = config.getString(Keys.TIME_PROTOCOLS); if (protocolList != null) { protocols = new HashSet<>(Arrays.asList(protocolList.split("[, ]"))); } else { -- cgit v1.2.3 From 481a902538b951a420d00c32063e0984e4e922d6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 06:48:48 -0700 Subject: Inject data source --- src/main/java/org/traccar/Context.java | 6 +- src/main/java/org/traccar/Main.java | 3 +- src/main/java/org/traccar/MainModule.java | 12 ++- .../java/org/traccar/database/DataManager.java | 97 +------------------ .../java/org/traccar/storage/DatabaseModule.java | 103 +++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 22 +++-- 6 files changed, 130 insertions(+), 113 deletions(-) create mode 100644 src/main/java/org/traccar/storage/DatabaseModule.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 5eaa1e15c..00ab05d57 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -28,6 +28,7 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.session.ConnectionManager; +import org.traccar.storage.Storage; public final class Context { @@ -82,7 +83,7 @@ public final class Context { } if (config.hasKey(Keys.DATABASE_URL)) { - dataManager = new DataManager(config); + dataManager = new DataManager(config, Main.getInjector().getInstance(Storage.class)); } if (dataManager != null) { @@ -93,7 +94,8 @@ public final class Context { identityManager = deviceManager; - permissionsManager = new PermissionsManager(dataManager, dataManager.getStorage()); + permissionsManager = new PermissionsManager( + dataManager, Main.getInjector().getInstance(Storage.class)); } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 412ac1f5e..72eeb5885 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; +import org.traccar.storage.DatabaseModule; import org.traccar.web.WebServer; import java.io.File; @@ -114,7 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new ServletModule()); + injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new ServletModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index dd7e375d3..4e95b2be0 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,12 +30,10 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.LdapProvider; -import org.traccar.helper.SanitizerModule; -import org.traccar.notification.EventForwarder; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; @@ -64,17 +62,21 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.helper.SanitizerModule; +import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; +import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; +import javax.sql.DataSource; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; @@ -108,8 +110,8 @@ public class MainModule extends AbstractModule { } @Provides - public static Storage provideStorage() { - return Context.getDataManager().getStorage(); + public static Storage provideStorage(DataSource dataSource, ObjectMapper objectMapper) { + return new DatabaseStorage(dataSource, objectMapper); } @Provides diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 6921634dd..9ffe1fe97 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -15,16 +15,6 @@ */ package org.traccar.database; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import liquibase.Contexts; -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.exception.LiquibaseException; -import liquibase.resource.FileSystemResourceAccessor; -import liquibase.resource.ResourceAccessor; import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -34,7 +24,6 @@ import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -43,100 +32,18 @@ import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.sql.DataSource; -import java.io.File; -import java.lang.reflect.Method; -import java.net.URL; import java.util.Collection; import java.util.Date; public class DataManager { - private final Config config; - - private DataSource dataSource; - - public DataSource getDataSource() { - return dataSource; - } - private final Storage storage; - public Storage getStorage() { - return storage; - } - private final boolean forceLdap; - public DataManager(Config config) throws Exception { - this.config = config; - + public DataManager(Config config, Storage storage) throws Exception { + this.storage = storage; forceLdap = config.getBoolean(Keys.LDAP_FORCE); - - initDatabase(); - initDatabaseSchema(); - - storage = new DatabaseStorage(dataSource, Main.getInjector().getInstance(ObjectMapper.class)); - } - - private void initDatabase() throws Exception { - - String driverFile = config.getString(Keys.DATABASE_DRIVER_FILE); - if (driverFile != null) { - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - try { - Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - method.invoke(classLoader, new File(driverFile).toURI().toURL()); - } catch (NoSuchMethodException e) { - Method method = classLoader.getClass() - .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); - method.setAccessible(true); - method.invoke(classLoader, driverFile); - } - } - - String driver = config.getString(Keys.DATABASE_DRIVER); - if (driver != null) { - Class.forName(driver); - } - - HikariConfig hikariConfig = new HikariConfig(); - hikariConfig.setDriverClassName(driver); - hikariConfig.setJdbcUrl(config.getString(Keys.DATABASE_URL)); - hikariConfig.setUsername(config.getString(Keys.DATABASE_USER)); - hikariConfig.setPassword(config.getString(Keys.DATABASE_PASSWORD)); - hikariConfig.setConnectionInitSql(config.getString(Keys.DATABASE_CHECK_CONNECTION)); - hikariConfig.setIdleTimeout(600000); - - int maxPoolSize = config.getInteger(Keys.DATABASE_MAX_POOL_SIZE); - if (maxPoolSize != 0) { - hikariConfig.setMaximumPoolSize(maxPoolSize); - } - - dataSource = new HikariDataSource(hikariConfig); - } - - private void initDatabaseSchema() throws LiquibaseException { - - if (config.hasKey(Keys.DATABASE_CHANGELOG)) { - - ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); - - Database database = DatabaseFactory.getInstance().openDatabase( - config.getString(Keys.DATABASE_URL), - config.getString(Keys.DATABASE_USER), - config.getString(Keys.DATABASE_PASSWORD), - config.getString(Keys.DATABASE_DRIVER), - null, null, null, resourceAccessor); - - String changelog = config.getString(Keys.DATABASE_CHANGELOG); - - try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { - liquibase.clearCheckSums(); - liquibase.update(new Contexts()); - } - } } public User login(String email, String password) throws StorageException { diff --git a/src/main/java/org/traccar/storage/DatabaseModule.java b/src/main/java/org/traccar/storage/DatabaseModule.java new file mode 100644 index 000000000..71bf84b34 --- /dev/null +++ b/src/main/java/org/traccar/storage/DatabaseModule.java @@ -0,0 +1,103 @@ +/* + * 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.storage; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import liquibase.Contexts; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.exception.LiquibaseException; +import liquibase.resource.FileSystemResourceAccessor; +import liquibase.resource.ResourceAccessor; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Singleton; +import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URL; + +public class DatabaseModule extends AbstractModule { + + @Singleton + @Provides + public static DataSource provideDataSource( + Config config) throws ReflectiveOperationException, IOException, LiquibaseException { + + String driverFile = config.getString(Keys.DATABASE_DRIVER_FILE); + if (driverFile != null) { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + try { + Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); + method.setAccessible(true); + method.invoke(classLoader, new File(driverFile).toURI().toURL()); + } catch (NoSuchMethodException e) { + Method method = classLoader.getClass() + .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); + method.setAccessible(true); + method.invoke(classLoader, driverFile); + } + } + + String driver = config.getString(Keys.DATABASE_DRIVER); + if (driver != null) { + Class.forName(driver); + } + + HikariConfig hikariConfig = new HikariConfig(); + hikariConfig.setDriverClassName(driver); + hikariConfig.setJdbcUrl(config.getString(Keys.DATABASE_URL)); + hikariConfig.setUsername(config.getString(Keys.DATABASE_USER)); + hikariConfig.setPassword(config.getString(Keys.DATABASE_PASSWORD)); + hikariConfig.setConnectionInitSql(config.getString(Keys.DATABASE_CHECK_CONNECTION)); + hikariConfig.setIdleTimeout(600000); + + int maxPoolSize = config.getInteger(Keys.DATABASE_MAX_POOL_SIZE); + if (maxPoolSize != 0) { + hikariConfig.setMaximumPoolSize(maxPoolSize); + } + + DataSource dataSource = new HikariDataSource(hikariConfig); + + if (config.hasKey(Keys.DATABASE_CHANGELOG)) { + + ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); + + Database database = DatabaseFactory.getInstance().openDatabase( + config.getString(Keys.DATABASE_URL), + config.getString(Keys.DATABASE_USER), + config.getString(Keys.DATABASE_PASSWORD), + config.getString(Keys.DATABASE_DRIVER), + null, null, null, resourceAccessor); + + String changelog = config.getString(Keys.DATABASE_CHANGELOG); + + try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { + liquibase.clearCheckSums(); + liquibase.update(new Contexts()); + } + } + + return dataSource; + } + +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 933e8c845..5d20966ad 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -47,7 +47,6 @@ import org.jvnet.hk2.guice.bridge.api.GuiceBridge; import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.LifecycleObject; import org.traccar.Main; import org.traccar.api.DateParameterConverterProvider; @@ -67,6 +66,7 @@ import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.sql.DataSource; import java.io.File; import java.io.IOException; import java.io.Writer; @@ -80,11 +80,13 @@ public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); private final Injector injector; + private final Config config; private final Server server; @Inject public WebServer(Injector injector, Config config) { this.injector = injector; + this.config = config; String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); if (address == null) { @@ -95,14 +97,14 @@ public class WebServer implements LifecycleObject { ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); - initApi(config, servletHandler); - initSessionConfig(config, servletHandler); + initApi(servletHandler); + initSessionConfig(servletHandler); if (config.getBoolean(Keys.WEB_CONSOLE)) { servletHandler.addServlet(new ServletHolder(new ConsoleServlet()), "/console/*"); } - initWebApp(config, servletHandler); + initWebApp(servletHandler); servletHandler.setErrorHandler(new ErrorHandler() { @Override @@ -119,7 +121,7 @@ public class WebServer implements LifecycleObject { }); HandlerList handlers = new HandlerList(); - initClientProxy(config, handlers); + initClientProxy(handlers); handlers.addHandler(servletHandler); handlers.addHandler(new GzipHandler()); server.setHandler(handlers); @@ -133,7 +135,7 @@ public class WebServer implements LifecycleObject { } } - private void initClientProxy(Config config, HandlerList handlers) { + private void initClientProxy(HandlerList handlers) { int port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix("osmand")); if (port != 0) { ServletContextHandler servletHandler = new ServletContextHandler() { @@ -153,7 +155,7 @@ public class WebServer implements LifecycleObject { } } - private void initWebApp(Config config, ServletContextHandler servletHandler) { + private void initWebApp(ServletContextHandler servletHandler) { ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); servletHolder.setInitParameter("resourceBase", new File(config.getString(Keys.WEB_PATH)).getAbsolutePath()); servletHolder.setInitParameter("dirAllowed", "false"); @@ -169,7 +171,7 @@ public class WebServer implements LifecycleObject { servletHandler.addServlet(servletHolder, "/*"); } - private void initApi(Config config, ServletContextHandler servletHandler) { + private void initApi(ServletContextHandler servletHandler) { servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); @@ -211,10 +213,10 @@ public class WebServer implements LifecycleObject { servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } - private void initSessionConfig(Config config, ServletContextHandler servletHandler) { + private void initSessionConfig(ServletContextHandler servletHandler) { if (config.getBoolean(Keys.WEB_PERSIST_SESSION)) { DatabaseAdaptor databaseAdaptor = new DatabaseAdaptor(); - databaseAdaptor.setDatasource(Context.getDataManager().getDataSource()); + databaseAdaptor.setDatasource(injector.getInstance(DataSource.class)); JDBCSessionDataStoreFactory jdbcSessionDataStoreFactory = new JDBCSessionDataStoreFactory(); jdbcSessionDataStoreFactory.setDatabaseAdaptor(databaseAdaptor); SessionHandler sessionHandler = servletHandler.getSessionHandler(); -- cgit v1.2.3 From d3fd20d4a4f7dc647e75c5a0cb962759630ed967 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 06:51:41 -0700 Subject: Inject data manager --- src/main/java/org/traccar/Context.java | 24 +++++++--------------- src/main/java/org/traccar/MainModule.java | 6 ------ .../java/org/traccar/database/DataManager.java | 8 ++------ 3 files changed, 9 insertions(+), 29 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 00ab05d57..cbbc73d76 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -16,7 +16,6 @@ package org.traccar; import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -47,12 +46,6 @@ public final class Context { return identityManager; } - private static DataManager dataManager; - - public static DataManager getDataManager() { - return dataManager; - } - private static GroupsManager groupsManager; public static GroupsManager getGroupsManager() { @@ -82,20 +75,17 @@ public final class Context { throw e; } - if (config.hasKey(Keys.DATABASE_URL)) { - dataManager = new DataManager(config, Main.getInjector().getInstance(Storage.class)); - } - - if (dataManager != null) { - groupsManager = new GroupsManager(dataManager); - deviceManager = new DeviceManager( - config, dataManager, Main.getInjector().getInstance(ConnectionManager.class)); - } + groupsManager = new GroupsManager(Main.getInjector().getInstance(DataManager.class)); + deviceManager = new DeviceManager( + config, + Main.getInjector().getInstance(DataManager.class), + Main.getInjector().getInstance(ConnectionManager.class)); identityManager = deviceManager; permissionsManager = new PermissionsManager( - dataManager, Main.getInjector().getInstance(Storage.class)); + Main.getInjector().getInstance(DataManager.class), + Main.getInjector().getInstance(Storage.class)); } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 4e95b2be0..aac11e619 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,7 +30,6 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; @@ -114,11 +113,6 @@ public class MainModule extends AbstractModule { return new DatabaseStorage(dataSource, objectMapper); } - @Provides - public static DataManager provideDataManager() { - return Context.getDataManager(); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 9ffe1fe97..3cad2dd63 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -32,6 +32,7 @@ import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; +import javax.inject.Inject; import java.util.Collection; import java.util.Date; @@ -41,6 +42,7 @@ public class DataManager { private final boolean forceLdap; + @Inject public DataManager(Config config, Storage storage) throws Exception { this.storage = storage; forceLdap = config.getBoolean(Keys.LDAP_FORCE); @@ -68,12 +70,6 @@ public class DataManager { return null; } - public void updateUserPassword(User user) throws StorageException { - storage.updateObject(user, new Request( - new Columns.Include("hashedPassword", "salt"), - new Condition.Equals("id", "id"))); - } - public void updateDeviceStatus(Device device) throws StorageException { storage.updateObject(device, new Request( new Columns.Include("lastUpdate"), -- cgit v1.2.3 From d3e83f9fa0d066e5a15fde225599cc43071c031a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 07:09:00 -0700 Subject: Remove groups manager --- src/main/java/org/traccar/Context.java | 13 +-- src/main/java/org/traccar/WebDataHandler.java | 8 +- .../java/org/traccar/api/BaseObjectResource.java | 11 +- .../java/org/traccar/database/DeviceManager.java | 9 +- .../traccar/database/ExtendedObjectManager.java | 115 --------------------- .../java/org/traccar/database/GroupsManager.java | 64 ------------ .../org/traccar/database/PermissionsManager.java | 11 +- .../org/traccar/reports/EventsReportProvider.java | 5 +- .../org/traccar/reports/RouteReportProvider.java | 8 +- .../org/traccar/reports/StopsReportProvider.java | 8 +- .../org/traccar/reports/TripsReportProvider.java | 8 +- src/test/java/org/traccar/WebDataHandlerTest.java | 3 +- 12 files changed, 48 insertions(+), 215 deletions(-) delete mode 100644 src/main/java/org/traccar/database/ExtendedObjectManager.java delete mode 100644 src/main/java/org/traccar/database/GroupsManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index cbbc73d76..9e8e3c521 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -19,14 +19,13 @@ import org.traccar.config.Config; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Group; import org.traccar.session.ConnectionManager; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; public final class Context { @@ -46,12 +45,6 @@ public final class Context { return identityManager; } - private static GroupsManager groupsManager; - - public static GroupsManager getGroupsManager() { - return groupsManager; - } - private static DeviceManager deviceManager; public static DeviceManager getDeviceManager() { @@ -75,9 +68,9 @@ public final class Context { throw e; } - groupsManager = new GroupsManager(Main.getInjector().getInstance(DataManager.class)); deviceManager = new DeviceManager( config, + Main.getInjector().getInstance(CacheManager.class), Main.getInjector().getInstance(DataManager.class), Main.getInjector().getInstance(ConnectionManager.class)); @@ -92,8 +85,6 @@ public final class Context { public static BaseObjectManager getManager(Class clazz) { if (clazz.equals(Device.class)) { return (BaseObjectManager) deviceManager; - } else if (clazz.equals(Group.class)) { - return (BaseObjectManager) groupsManager; } return null; } diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 2c0aa0f8e..db99ecaf8 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -31,6 +31,7 @@ import org.traccar.helper.Checksum; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.Group; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.core.HttpHeaders; @@ -60,6 +61,7 @@ public class WebDataHandler extends BaseDataHandler { private static final String KEY_POSITION = "position"; private static final String KEY_DEVICE = "device"; + private final CacheManager cacheManager; private final IdentityManager identityManager; private final ObjectMapper objectMapper; private final Client client; @@ -78,8 +80,10 @@ public class WebDataHandler extends BaseDataHandler { @Inject public WebDataHandler( - Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) { + Config config, CacheManager cacheManager, IdentityManager identityManager, + ObjectMapper objectMapper, Client client) { + this.cacheManager = cacheManager; this.identityManager = identityManager; this.objectMapper = objectMapper; this.client = client; @@ -171,7 +175,7 @@ public class WebDataHandler extends BaseDataHandler { if (request.contains("{group}")) { String deviceGroupName = ""; if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + Group group = cacheManager.getObject(Group.class, device.getGroupId()); if (group != null) { deviceGroupName = group.getName(); } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index f8545a5d7..78aa12dbe 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -18,7 +18,6 @@ package org.traccar.api; import org.traccar.Context; import org.traccar.database.BaseObjectManager; -import org.traccar.database.ExtendedObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -92,10 +91,16 @@ public abstract class BaseObjectResource extends BaseResour public Response update(T entity) throws StorageException { permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); + if (entity instanceof User) { User before = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); permissionsService.checkUserUpdate(getUserId(), before, (User) entity); + } else if (entity instanceof Group) { + Group group = (Group) entity; + if (group.getId() == group.getGroupId()) { + throw new IllegalArgumentException("Cycle in group hierarchy"); + } } BaseObjectManager manager = Context.getManager(baseClass); @@ -125,9 +130,6 @@ public abstract class BaseObjectResource extends BaseResour BaseObjectManager manager = Context.getManager(baseClass); if (manager != null) { manager.removeItem(id); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager) manager).refreshExtendedPermissions(); - } } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } @@ -137,7 +139,6 @@ public abstract class BaseObjectResource extends BaseResour if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { if (baseClass.equals(Group.class)) { - Context.getGroupsManager().refreshItems(); Context.getDeviceManager().updateDeviceCache(true); } Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 9ba486988..29c17c41f 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -46,6 +46,7 @@ public class DeviceManager extends BaseObjectManager implements Identity private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); private final Config config; + private final CacheManager cacheManager; private final ConnectionManager connectionManager; private final long dataRefreshDelay; @@ -56,9 +57,11 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map deviceStates = new ConcurrentHashMap<>(); - public DeviceManager(Config config, DataManager dataManager, ConnectionManager connectionManager) { + public DeviceManager( + Config config, CacheManager cacheManager, DataManager dataManager, ConnectionManager connectionManager) { super(dataManager, Device.class); this.config = config; + this.cacheManager = cacheManager; this.connectionManager = connectionManager; try { writeLock(); @@ -351,8 +354,8 @@ public class DeviceManager extends BaseObjectManager implements Identity result = device.getAttributes().get(attributeName); if (result == null) { long groupId = device.getGroupId(); - while (groupId != 0) { - Group group = Context.getGroupsManager().getById(groupId); + while (groupId > 0) { + Group group = cacheManager.getObject(Group.class, device.getGroupId()); if (group != null) { result = group.getAttributes().get(attributeName); if (result != null) { diff --git a/src/main/java/org/traccar/database/ExtendedObjectManager.java b/src/main/java/org/traccar/database/ExtendedObjectManager.java deleted file mode 100644 index fe0ebb96e..000000000 --- a/src/main/java/org/traccar/database/ExtendedObjectManager.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.database; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Permission; -import org.traccar.model.BaseModel; -import org.traccar.storage.StorageException; - -public abstract class ExtendedObjectManager extends SimpleObjectManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ExtendedObjectManager.class); - - private final Map> deviceItems = new ConcurrentHashMap<>(); - private final Map> deviceItemsWithGroups = new ConcurrentHashMap<>(); - private final Map> groupItems = new ConcurrentHashMap<>(); - - protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { - super(dataManager, baseClass); - refreshExtendedPermissions(); - } - - public Set getAllDeviceItems(long deviceId) { - try { - readLock(); - Set result = deviceItemsWithGroups.get(deviceId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - - @Override - public void removeItem(long itemId) throws StorageException { - super.removeItem(itemId); - refreshExtendedPermissions(); - } - - public void refreshExtendedPermissions() { - if (getDataManager() != null) { - try { - Collection databaseGroupPermissions = - getDataManager().getPermissions(Group.class, getBaseClass()); - - Collection databaseDevicePermissions = - getDataManager().getPermissions(Device.class, getBaseClass()); - - writeLock(); - - groupItems.clear(); - deviceItems.clear(); - deviceItemsWithGroups.clear(); - - for (Permission groupPermission : databaseGroupPermissions) { - groupItems - .computeIfAbsent(groupPermission.getOwnerId(), key -> new HashSet<>()) - .add(groupPermission.getPropertyId()); - } - - for (Permission devicePermission : databaseDevicePermissions) { - deviceItems - .computeIfAbsent(devicePermission.getOwnerId(), key -> new HashSet<>()) - .add(devicePermission.getPropertyId()); - deviceItemsWithGroups - .computeIfAbsent(devicePermission.getOwnerId(), key -> new HashSet<>()) - .add(devicePermission.getPropertyId()); - } - - for (Device device : getDataManager().getObjects(Device.class)) { - long groupId = device.getGroupId(); - while (groupId > 0) { - deviceItemsWithGroups - .computeIfAbsent(device.getId(), key -> new HashSet<>()) - .addAll(groupItems.getOrDefault(groupId, new HashSet<>())); - Group group = Context.getGroupsManager().getById(groupId); - groupId = group != null ? group.getGroupId() : 0; - } - } - - } catch (StorageException | ClassNotFoundException error) { - LOGGER.warn("Refresh permissions error", error); - } finally { - writeUnlock(); - } - } - } -} diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java deleted file mode 100644 index 4df848042..000000000 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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"); - * 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.database; - -import java.util.HashSet; -import java.util.Set; - -import org.traccar.model.Group; -import org.traccar.storage.StorageException; - -public class GroupsManager extends BaseObjectManager { - - public GroupsManager(DataManager dataManager) { - super(dataManager, Group.class); - } - - private void checkGroupCycles(Group group) { - Set groups = new HashSet<>(); - while (group != null) { - if (groups.contains(group.getId())) { - throw new IllegalArgumentException("Cycle in group hierarchy"); - } - groups.add(group.getId()); - group = getById(group.getGroupId()); - } - } - - @Override - public Set getAllItems() { - Set result = super.getAllItems(); - if (result.isEmpty()) { - refreshItems(); - result = super.getAllItems(); - } - return result; - } - - @Override - protected void addNewItem(Group group) { - checkGroupCycles(group); - super.addNewItem(group); - } - - @Override - public void updateItem(Group group) throws StorageException { - checkGroupCycles(group); - super.updateItem(group); - } - -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 833480eea..595e236fa 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -162,9 +162,8 @@ public class PermissionsManager { groupPermissions.clear(); devicePermissions.clear(); try { - GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( - Context.getGroupsManager().getAllItems()), - Context.getDeviceManager().getAllDevices()); + var groups = dataManager.getObjects(Group.class); + GroupTree groupTree = new GroupTree(groups, Context.getDeviceManager().getAllDevices()); for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); Set userDevicePermissions = getDevicePermissions(groupPermission.getOwnerId()); @@ -182,9 +181,9 @@ public class PermissionsManager { } groupDevices.clear(); - for (long groupId : Context.getGroupsManager().getAllItems()) { - for (Device device : groupTree.getDevices(groupId)) { - getGroupDevices(groupId).add(device.getId()); + for (var group : groups) { + for (Device device : groupTree.getDevices(group.getId())) { + getGroupDevices(group.getId()).add(device.getId()); } } diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 5148695a9..b1f7149a2 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -134,8 +134,9 @@ public class EventsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceEvents.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index b1a806960..903dfe369 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -77,8 +80,9 @@ public class RouteReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceRoutes.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index a6a9a94cc..b9d36eb97 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -85,8 +88,9 @@ public class StopsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceStops.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index bff559664..97cfccf74 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -85,8 +88,9 @@ public class TripsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceTrips.setGroupName(group.getName()); } diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index aaec9f530..ff9c80ce6 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -6,6 +6,7 @@ import org.traccar.config.Keys; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyLong; @@ -30,7 +31,7 @@ public class WebDataHandlerTest extends ProtocolTest { var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); - WebDataHandler handler = new WebDataHandler(config, identityManager, null, null); + WebDataHandler handler = new WebDataHandler(config, mock(CacheManager.class), identityManager, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", -- cgit v1.2.3 From cc342a9ba371b0dca8d87ca9e74c5907ccb58bc6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 07:18:33 -0700 Subject: Permissions manager refactor --- .../traccar/api/resource/PermissionsResource.java | 5 ++-- .../org/traccar/api/resource/ServerResource.java | 4 +--- .../java/org/traccar/database/DeviceManager.java | 2 +- .../org/traccar/database/PermissionsManager.java | 27 ---------------------- .../org/traccar/session/ConnectionManager.java | 14 +++++------ 5 files changed, 12 insertions(+), 40 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 36ee0c213..b92e6e9d9 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -20,6 +20,7 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Permission; +import org.traccar.model.UserRestrictions; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; @@ -65,7 +66,7 @@ public class PermissionsResource extends BaseResource { @Path("bulk") @POST public Response add(List> entities) throws StorageException, ClassNotFoundException { - Context.getPermissionsManager().checkReadonly(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); @@ -90,7 +91,7 @@ public class PermissionsResource extends BaseResource { @DELETE @Path("bulk") public Response remove(List> entities) throws StorageException, ClassNotFoundException { - Context.getPermissionsManager().checkReadonly(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 18230a2b3..b66f5a931 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -15,7 +15,6 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.geocoder.Geocoder; @@ -66,8 +65,7 @@ public class ServerResource extends BaseResource { @PUT public Response update(Server entity) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getPermissionsManager().updateServer(entity); + permissionsService.checkAdmin(getUserId()); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 29c17c41f..bd100245c 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -368,7 +368,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } } if (result == null && lookupServer) { - Server server = Context.getPermissionsManager().getServer(); + Server server = cacheManager.getServer(); result = server.getAttributes().get(attributeName); } if (result == null && lookupConfig) { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 595e236fa..3d4e6425a 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -22,7 +22,6 @@ import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; -import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -44,8 +43,6 @@ public class PermissionsManager { private final DataManager dataManager; private final Storage storage; - private volatile Server server; - private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map> groupPermissions = new HashMap<>(); @@ -56,7 +53,6 @@ public class PermissionsManager { public PermissionsManager(DataManager dataManager, Storage storage) { this.dataManager = dataManager; this.storage = storage; - refreshServer(); refreshDeviceAndGroupPermissions(); } @@ -148,14 +144,6 @@ public class PermissionsManager { } } - public void refreshServer() { - try { - server = dataManager.getServer(); - } catch (StorageException error) { - LOGGER.warn("Refresh server config error", error); - } - } - public final void refreshDeviceAndGroupPermissions() { writeLock(); try { @@ -229,12 +217,6 @@ public class PermissionsManager { return user != null && user.getReadonly(); } - public void checkReadonly(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { - throw new SecurityException("Account is readonly"); - } - } - public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); if (user == null) { @@ -265,15 +247,6 @@ public class PermissionsManager { } } - public Server getServer() { - return server; - } - - public void updateServer(Server server) throws StorageException { - dataManager.updateObject(server); - this.server = server; - } - public User login(String email, String password) throws StorageException { User user = dataManager.login(email, password); if (user != null) { diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index dc714379b..c8c07f9c7 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -31,6 +31,7 @@ import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -297,9 +298,9 @@ public class ConnectionManager { } public synchronized void updateDevice(Device device) { - for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { + for (User user : cacheManager.getDeviceObjects(device.getId(), User.class)) { + if (listeners.containsKey(user.getId())) { + for (UpdateListener listener : listeners.get(user.getId())) { listener.onUpdateDevice(device); } } @@ -308,10 +309,9 @@ public class ConnectionManager { public synchronized void updatePosition(Position position) { long deviceId = position.getDeviceId(); - - for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { + for (User user : cacheManager.getDeviceObjects(deviceId, User.class)) { + if (listeners.containsKey(user.getId())) { + for (UpdateListener listener : listeners.get(user.getId())) { listener.onUpdatePosition(position); } } -- cgit v1.2.3 From e74c64f27dc30473d9ef866c5c52e3dd6bee2fc3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 07:45:19 -0700 Subject: Refactor device permissions check --- src/main/java/org/traccar/api/MediaFilter.java | 23 ++++++++++---- .../org/traccar/api/resource/EventResource.java | 4 +-- .../traccar/api/security/PermissionsService.java | 13 ++++++++ .../org/traccar/database/PermissionsManager.java | 35 ---------------------- .../org/traccar/reports/EventsReportProvider.java | 6 ++-- .../org/traccar/reports/RouteReportProvider.java | 6 ++-- .../org/traccar/reports/StopsReportProvider.java | 6 ++-- .../org/traccar/reports/SummaryReportProvider.java | 4 +-- .../org/traccar/reports/TripsReportProvider.java | 6 ++-- .../org/traccar/reports/common/ReportUtils.java | 12 ++++++++ 10 files changed, 62 insertions(+), 53 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index 0433147f8..c6ac811d7 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -28,12 +28,17 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.traccar.Context; import org.traccar.Main; import org.traccar.api.resource.SessionResource; +import org.traccar.api.security.PermissionsService; import org.traccar.database.StatisticsManager; import org.traccar.helper.Log; import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; public class MediaFilter implements Filter { @@ -44,6 +49,11 @@ public class MediaFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + PermissionsService permissionsService = Main.getInjector().getInstance(PermissionsService.class); + Storage storage = Main.getInjector().getInstance(Storage.class); + StatisticsManager statisticsManager = Main.getInjector().getInstance(StatisticsManager.class); + HttpServletResponse httpResponse = (HttpServletResponse) response; try { HttpSession session = ((HttpServletRequest) request).getSession(false); @@ -51,8 +61,8 @@ public class MediaFilter implements Filter { if (session != null) { userId = (Long) session.getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); + permissionsService.checkUserEnabled(userId); + statisticsManager.registerRequest(userId); } } if (userId == null) { @@ -63,16 +73,17 @@ public class MediaFilter implements Filter { String path = ((HttpServletRequest) request).getPathInfo(); String[] parts = path != null ? path.split("/") : null; if (parts != null && parts.length >= 2) { - Device device = Context.getDeviceManager().getByUniqueId(parts[1]); + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", parts[1]))); if (device != null) { - Context.getPermissionsManager().checkDevice(userId, device.getId()); + permissionsService.checkPermission(Device.class, userId, device.getId()); chain.doFilter(request, response); return; } } httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); - } catch (SecurityException e) { + } catch (SecurityException | StorageException e) { httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); httpResponse.getWriter().println(Log.exceptionStack(e)); } diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index eb373946a..3870e9af9 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -15,8 +15,8 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -45,7 +45,7 @@ public class EventResource extends BaseResource { if (event == null) { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } - Context.getPermissionsManager().checkDevice(getUserId(), event.getDeviceId()); + permissionsService.checkPermission(Device.class, getUserId(), event.getDeviceId()); return event; } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index f39ded2b7..8732a0d04 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -92,6 +92,19 @@ public class PermissionsService { } } + public void checkUserEnabled(long userId) throws StorageException, SecurityException { + User user = getUser(userId); + if (user == null) { + throw new SecurityException("Unknown account"); + } + if (user.getDisabled()) { + throw new SecurityException("Account is disabled"); + } + if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { + throw new SecurityException("Account has expired"); + } + } + public void checkEdit(long userId, Class clazz, boolean addition) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { boolean denied = false; diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 3d4e6425a..f6fbd9489 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -18,7 +18,6 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; @@ -117,21 +116,6 @@ public class PermissionsManager { } } - public Set getDeviceUsers(long deviceId) { - Device device = Context.getIdentityManager().getById(deviceId); - if (device != null && !device.getDisabled()) { - return getAllDeviceUsers(deviceId); - } else { - Set result = new HashSet<>(); - for (long userId : getAllDeviceUsers(deviceId)) { - if (getUserAdmin(userId)) { - result.add(userId); - } - } - return result; - } - } - public Set getGroupDevices(long groupId) { readLock(); try { @@ -195,12 +179,6 @@ public class PermissionsManager { return user != null && user.getAdministrator(); } - public void checkAdmin(long userId) throws SecurityException { - if (!getUserAdmin(userId)) { - throw new SecurityException("Admin access required"); - } - } - public boolean getUserManager(long userId) { User user = getUser(userId); return user != null && user.getUserLimit() != 0; @@ -212,11 +190,6 @@ public class PermissionsManager { } } - public boolean getUserReadonly(long userId) { - User user = getUser(userId); - return user != null && user.getReadonly(); - } - public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); if (user == null) { @@ -230,14 +203,6 @@ public class PermissionsManager { } } - public void checkDevice(long userId, long deviceId) throws SecurityException { - try { - new PermissionsService(storage).checkPermission(Device.class, userId, deviceId); - } catch (StorageException e) { - throw new RuntimeException(e); - } - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index b1f7149a2..4db842fdb 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -74,9 +74,10 @@ public class EventsReportProvider { long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Event event : events) { @@ -98,12 +99,13 @@ public class EventsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 903dfe369..b4401bc87 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -59,9 +59,10 @@ public class RouteReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(PositionUtil.getPositions(storage, deviceId, from, to)); } return result; @@ -71,10 +72,11 @@ public class RouteReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); var positions = PositionUtil.getPositions(storage, deviceId, from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index b9d36eb97..a63d7ee21 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -67,9 +67,10 @@ public class StopsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectStops(deviceId, from, to)); } return result; @@ -79,10 +80,11 @@ public class StopsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection stops = detectStops(deviceId, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 68976b987..86d76b4e3 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -146,9 +146,10 @@ public class SummaryReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { @@ -162,7 +163,6 @@ public class SummaryReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException, IOException { - reportUtils.checkPeriodLimit(from, to); Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "summary.xlsx").toFile(); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 97cfccf74..bec4c39fd 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -67,9 +67,10 @@ public class TripsReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectTrips(deviceId, from, to)); } return result; @@ -79,10 +80,11 @@ public class TripsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection trips = detectTrips(deviceId, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 95c43f8a0..84866a67b 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -38,8 +38,10 @@ import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; +import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Event; +import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; @@ -109,6 +111,16 @@ public class ReportUtils { } } + public void checkPermissions( + long userId, Collection deviceIds, Collection groupIds) throws StorageException { + for (long deviceId : deviceIds) { + permissionsService.checkPermission(Device.class, userId, deviceId); + } + for (long groupId : groupIds) { + permissionsService.checkPermission(Group.class, userId, groupId); + } + } + public Collection getDeviceList(Collection deviceIds, Collection groupIds) { Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { -- cgit v1.2.3 From 51cdee534cd9990d1de173814fe95c55dead4934 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 08:24:48 -0700 Subject: Refactor login --- src/main/java/org/traccar/api/MediaFilter.java | 1 - .../org/traccar/api/resource/SessionResource.java | 23 +++--- .../traccar/api/security/PermissionsService.java | 13 ---- .../api/security/SecurityRequestFilter.java | 7 +- .../java/org/traccar/database/DataManager.java | 31 +------- .../java/org/traccar/database/LoginService.java | 89 ++++++++++++++++++++++ .../org/traccar/database/PermissionsManager.java | 22 ------ 7 files changed, 104 insertions(+), 82 deletions(-) create mode 100644 src/main/java/org/traccar/database/LoginService.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index c6ac811d7..e0609871a 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -61,7 +61,6 @@ public class MediaFilter implements Filter { if (session != null) { userId = (Long) session.getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - permissionsService.checkUserEnabled(userId); statisticsManager.registerRequest(userId); } } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index a0bf0cba5..70561f997 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -15,18 +15,16 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.LoginService; import org.traccar.helper.DataConverter; import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; import org.traccar.model.User; import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -54,6 +52,9 @@ public class SessionResource extends BaseResource { public static final String USER_COOKIE_KEY = "user"; public static final String PASS_COOKIE_KEY = "password"; + @Inject + private LoginService loginService; + @javax.ws.rs.core.Context private HttpServletRequest request; @@ -62,11 +63,10 @@ public class SessionResource extends BaseResource { public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException { if (token != null) { - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("token", "token", token))); + User user = loginService.login(token); if (user != null) { - Context.getPermissionsManager().checkUserEnabled(user.getId()); request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } } @@ -90,18 +90,17 @@ public class SessionResource extends BaseResource { } } if (email != null && password != null) { - User user = Context.getPermissionsManager().login(email, password); + User user = loginService.login(email, password); if (user != null) { - Context.getPermissionsManager().checkUserEnabled(user.getId()); request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } } } else { - Context.getPermissionsManager().checkUserEnabled(userId); - return Context.getPermissionsManager().getUser(userId); + return permissionsService.getUser(userId); } @@ -112,7 +111,7 @@ public class SessionResource extends BaseResource { @POST public User add( @FormParam("email") String email, @FormParam("password") String password) throws StorageException { - User user = Context.getPermissionsManager().login(email, password); + User user = loginService.login(email, password); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 8732a0d04..f39ded2b7 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -92,19 +92,6 @@ public class PermissionsService { } } - public void checkUserEnabled(long userId) throws StorageException, SecurityException { - User user = getUser(userId); - if (user == null) { - throw new SecurityException("Unknown account"); - } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } - } - public void checkEdit(long userId, Class clazz, boolean addition) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { boolean denied = false; diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index 9f20acb40..ad45dc112 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 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,9 +17,9 @@ package org.traccar.api.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; import org.traccar.api.resource.SessionResource; +import org.traccar.database.LoginService; import org.traccar.database.StatisticsManager; import org.traccar.helper.DataConverter; import org.traccar.model.User; @@ -77,7 +77,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { try { String[] auth = decodeBasicAuth(authHeader); - User user = Context.getPermissionsManager().login(auth[0], auth[1]); + User user = Main.getInjector().getInstance(LoginService.class).login(auth[0], auth[1]); if (user != null) { Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); @@ -90,7 +90,6 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); securityContext = new UserSecurityContext(new UserPrincipal(userId)); } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 3cad2dd63..aa600e375 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -15,15 +15,11 @@ */ package org.traccar.database; -import org.traccar.Main; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; -import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -40,34 +36,9 @@ public class DataManager { private final Storage storage; - private final boolean forceLdap; - @Inject - public DataManager(Config config, Storage storage) throws Exception { + public DataManager(Storage storage) throws Exception { this.storage = storage; - forceLdap = config.getBoolean(Keys.LDAP_FORCE); - } - - public User login(String email, String password) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.Include("id", "login", "hashedPassword", "salt"), - new Condition.Or( - new Condition.Equals("email", "email", email.trim()), - new Condition.Equals("login", "email")))); - LdapProvider ldapProvider = Main.getInjector().getInstance(LdapProvider.class); - if (user != null) { - if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) - || !forceLdap && user.isPasswordValid(password)) { - return user; - } - } else { - if (ldapProvider != null && ldapProvider.login(email, password)) { - user = ldapProvider.getUser(email); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - return user; - } - } - return null; } public void updateDeviceStatus(Device device) throws StorageException { diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java new file mode 100644 index 000000000..a30e443b5 --- /dev/null +++ b/src/main/java/org/traccar/database/LoginService.java @@ -0,0 +1,89 @@ +/* + * 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.database; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +public class LoginService { + + private final Storage storage; + private final LdapProvider ldapProvider; + + private final boolean forceLdap; + + @Inject + public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { + this.storage = storage; + this.ldapProvider = ldapProvider; + forceLdap = config.getBoolean(Keys.LDAP_FORCE); + } + + public User login(String token) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("token", "token", token))); + if (user != null) { + checkUserEnabled(user); + } + return user; + } + + public User login(String email, String password) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.Include("id", "login", "hashedPassword", "salt"), + new Condition.Or( + new Condition.Equals("email", "email", email.trim()), + new Condition.Equals("login", "email")))); + if (user != null) { + if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) + || !forceLdap && user.isPasswordValid(password)) { + checkUserEnabled(user); + return user; + } + } else { + if (ldapProvider != null && ldapProvider.login(email, password)) { + user = ldapProvider.getUser(email); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + return null; + } + + + private void checkUserEnabled(User user) throws SecurityException { + if (user == null) { + throw new SecurityException("Unknown account"); + } + if (user.getDisabled()) { + throw new SecurityException("Account is disabled"); + } + if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { + throw new SecurityException("Account has expired"); + } + } + +} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index f6fbd9489..4ac27c717 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -190,19 +190,6 @@ public class PermissionsManager { } } - public void checkUserEnabled(long userId) throws SecurityException { - User user = getUser(userId); - if (user == null) { - throw new SecurityException("Unknown account"); - } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) @@ -212,13 +199,4 @@ public class PermissionsManager { } } - public User login(String email, String password) throws StorageException { - User user = dataManager.login(email, password); - if (user != null) { - checkUserEnabled(user.getId()); - return getUser(user.getId()); - } - return null; - } - } -- cgit v1.2.3 From b47eca7a90438e738eb1486664717cccc277865f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 15:07:29 -0700 Subject: Refactor web server code --- src/main/java/org/traccar/LifecycleObject.java | 2 +- src/main/java/org/traccar/Main.java | 6 ++- src/main/java/org/traccar/ServerManager.java | 11 +++-- .../org/traccar/web/GuiceBridgeInitializer.java | 49 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 49 ++++------------------ 5 files changed, 70 insertions(+), 47 deletions(-) create mode 100644 src/main/java/org/traccar/web/GuiceBridgeInitializer.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/LifecycleObject.java b/src/main/java/org/traccar/LifecycleObject.java index 7af21d528..fe0dc698a 100644 --- a/src/main/java/org/traccar/LifecycleObject.java +++ b/src/main/java/org/traccar/LifecycleObject.java @@ -17,5 +17,5 @@ package org.traccar; public interface LifecycleObject { void start() throws Exception; - void stop(); + void stop() throws Exception; } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 72eeb5885..e3286fd5e 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -137,7 +137,11 @@ public final class Main { LOGGER.info("Stopping server..."); for (var service : services) { - service.stop(); + try { + service.stop(); + } catch (Exception e) { + throw new RuntimeException(e); + } } })); } catch (Exception e) { diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index ffb15d8ca..99fb9a494 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -72,11 +72,14 @@ public class ServerManager implements LifecycleObject { } @Override - public void stop() { - for (TrackerConnector connector: connectorList) { - connector.stop(); + public void stop() throws Exception { + try { + for (TrackerConnector connector : connectorList) { + connector.stop(); + } + } finally { + GlobalTimer.release(); } - GlobalTimer.release(); } } diff --git a/src/main/java/org/traccar/web/GuiceBridgeInitializer.java b/src/main/java/org/traccar/web/GuiceBridgeInitializer.java new file mode 100644 index 000000000..fc9c88f3b --- /dev/null +++ b/src/main/java/org/traccar/web/GuiceBridgeInitializer.java @@ -0,0 +1,49 @@ +/* + * 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.web; + +import com.google.inject.Injector; +import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager; +import org.glassfish.jersey.server.spi.Container; +import org.glassfish.jersey.server.spi.ContainerLifecycleListener; +import org.jvnet.hk2.guice.bridge.api.GuiceBridge; +import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; + +public class GuiceBridgeInitializer implements ContainerLifecycleListener { + + private final Injector injector; + + public GuiceBridgeInitializer(Injector injector) { + this.injector = injector; + } + + @Override + public void onStartup(Container container) { + var injectionManager = container.getApplicationHandler().getInjectionManager(); + var serviceLocator = ((ImmediateHk2InjectionManager) injectionManager).getServiceLocator(); + GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); + var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); + guiceBridge.bridgeGuiceInjector(injector); + } + + @Override + public void onReload(Container container) { + } + + @Override + public void onShutdown(Container container) { + } +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 5d20966ad..36f3d7682 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -37,27 +37,21 @@ import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; -import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.spi.Container; -import org.glassfish.jersey.server.spi.ContainerLifecycleListener; import org.glassfish.jersey.servlet.ServletContainer; -import org.jvnet.hk2.guice.bridge.api.GuiceBridge; -import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; -import org.traccar.Main; -import org.traccar.api.DateParameterConverterProvider; -import org.traccar.config.Config; import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; +import org.traccar.api.DateParameterConverterProvider; import org.traccar.api.MediaFilter; import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; -import org.traccar.api.security.SecurityRequestFilter; import org.traccar.api.resource.ServerResource; +import org.traccar.api.security.SecurityRequestFilter; +import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; @@ -77,8 +71,6 @@ import java.util.EnumSet; public class WebServer implements LifecycleObject { - private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); - private final Injector injector; private final Config config; private final Server server; @@ -192,24 +184,7 @@ public class WebServer implements LifecycleObject { JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); - resourceConfig.register(new ContainerLifecycleListener() { - @Override - public void onStartup(Container container) { - var injectionManager = container.getApplicationHandler().getInjectionManager(); - var serviceLocator = ((ImmediateHk2InjectionManager) injectionManager).getServiceLocator(); - GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); - var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); - guiceBridge.bridgeGuiceInjector(Main.getInjector()); - } - - @Override - public void onReload(Container container) { - } - - @Override - public void onShutdown(Container container) { - } - }); + resourceConfig.register(new GuiceBridgeInitializer(injector)); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } @@ -251,21 +226,13 @@ public class WebServer implements LifecycleObject { } @Override - public void start() { - try { - server.start(); - } catch (Exception error) { - LOGGER.warn("Web server start failed", error); - } + public void start() throws Exception { + server.start(); } @Override - public void stop() { - try { - server.stop(); - } catch (Exception error) { - LOGGER.warn("Web server stop failed", error); - } + public void stop() throws Exception { + server.stop(); } } -- cgit v1.2.3 From b100cb211161d1014dfaa1ab532f1670c699e80d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 16:20:13 -0700 Subject: Improve web injection --- src/main/java/org/traccar/Main.java | 4 +- .../java/org/traccar/api/AsyncSocketServlet.java | 2 + src/main/java/org/traccar/api/MediaFilter.java | 47 +++++++++++++--------- .../java/org/traccar/api/ObjectMapperProvider.java | 13 +++--- src/main/java/org/traccar/web/WebModule.java | 29 +++++++++++++ src/main/java/org/traccar/web/WebServer.java | 25 +++++------- 6 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 src/main/java/org/traccar/web/WebModule.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index e3286fd5e..bf69b565d 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -17,12 +17,12 @@ package org.traccar; import com.google.inject.Guice; import com.google.inject.Injector; -import com.google.inject.servlet.ServletModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; import org.traccar.storage.DatabaseModule; +import org.traccar.web.WebModule; import org.traccar.web.WebServer; import java.io.File; @@ -115,7 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new ServletModule()); + injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new WebModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 317ec469e..7c532179b 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -24,9 +24,11 @@ import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; import javax.inject.Inject; +import javax.inject.Singleton; import javax.servlet.http.HttpSession; import java.time.Duration; +@Singleton public class AsyncSocketServlet extends JettyWebSocketServlet { private final ObjectMapper objectMapper; diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index e0609871a..6d95c66a8 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -16,19 +16,7 @@ */ package org.traccar.api; -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.traccar.Main; +import com.google.inject.Provider; import org.traccar.api.resource.SessionResource; import org.traccar.api.security.PermissionsService; import org.traccar.database.StatisticsManager; @@ -40,8 +28,35 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +@Singleton public class MediaFilter implements Filter { + private final Storage storage; + private final StatisticsManager statisticsManager; + private final Provider permissionsServiceProvider; + + @Inject + public MediaFilter( + Storage storage, StatisticsManager statisticsManager, + Provider permissionsServiceProvider) { + this.storage = storage; + this.statisticsManager = statisticsManager; + this.permissionsServiceProvider = permissionsServiceProvider; + } + @Override public void init(FilterConfig filterConfig) throws ServletException { } @@ -50,10 +65,6 @@ public class MediaFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - PermissionsService permissionsService = Main.getInjector().getInstance(PermissionsService.class); - Storage storage = Main.getInjector().getInstance(Storage.class); - StatisticsManager statisticsManager = Main.getInjector().getInstance(StatisticsManager.class); - HttpServletResponse httpResponse = (HttpServletResponse) response; try { HttpSession session = ((HttpServletRequest) request).getSession(false); @@ -75,7 +86,7 @@ public class MediaFilter implements Filter { Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", parts[1]))); if (device != null) { - permissionsService.checkPermission(Device.class, userId, device.getId()); + permissionsServiceProvider.get().checkPermission(Device.class, userId, device.getId()); chain.doFilter(request, response); return; } diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java index cb7adab6c..4d8b266fa 100644 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 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. @@ -16,17 +16,20 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; -import org.traccar.Main; import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; -@Provider public class ObjectMapperProvider implements ContextResolver { + private final ObjectMapper objectMapper; + + public ObjectMapperProvider(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @Override public ObjectMapper getContext(Class type) { - return Main.getInjector().getInstance(ObjectMapper.class); + return objectMapper; } } diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java new file mode 100644 index 000000000..6c133ff74 --- /dev/null +++ b/src/main/java/org/traccar/web/WebModule.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.web; + +import com.google.inject.servlet.ServletModule; +import org.traccar.api.AsyncSocketServlet; +import org.traccar.api.MediaFilter; + +public class WebModule extends ServletModule { + + @Override + protected void configureServlets() { + filter("/api/media/*").through(MediaFilter.class); + serve("/api/socket").with(AsyncSocketServlet.class); + } +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 36f3d7682..46e401779 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,6 +15,7 @@ */ package org.traccar.web; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Injector; import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; @@ -40,13 +41,9 @@ import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerI import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; -import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; import org.traccar.api.DateParameterConverterProvider; -import org.traccar.api.MediaFilter; import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; import org.traccar.api.resource.ServerResource; @@ -88,6 +85,8 @@ public class WebServer implements LifecycleObject { } ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + JettyWebSocketServletContainerInitializer.configure(servletHandler, null); + servletHandler.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class)); initApi(servletHandler); initSessionConfig(servletHandler); @@ -140,7 +139,7 @@ public class WebServer implements LifecycleObject { } } }; - ServletHolder servletHolder = new ServletHolder(new AsyncProxyServlet.Transparent()); + ServletHolder servletHolder = new ServletHolder(AsyncProxyServlet.Transparent.class); servletHolder.setInitParameter("proxyTo", "http://localhost:" + port); servletHandler.addServlet(servletHolder, "/"); handlers.addHandler(servletHandler); @@ -164,11 +163,6 @@ public class WebServer implements LifecycleObject { } private void initApi(ServletContextHandler servletHandler) { - servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); - - servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); - JettyWebSocketServletContainerInitializer.configure(servletHandler, null); - String mediaPath = config.getString(Keys.MEDIA_PATH); if (mediaPath != null) { ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); @@ -176,15 +170,18 @@ public class WebServer implements LifecycleObject { servletHolder.setInitParameter("dirAllowed", "false"); servletHolder.setInitParameter("pathInfoOnly", "true"); servletHandler.addServlet(servletHolder, "/api/media/*"); - servletHandler.addFilter(MediaFilter.class, "/api/media/*", EnumSet.allOf(DispatcherType.class)); } ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfig.register(new GuiceBridgeInitializer(injector)); + resourceConfig.register(new ObjectMapperProvider(injector.getInstance(ObjectMapper.class))); resourceConfig.registerClasses( - JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, - SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); + JacksonFeature.class, + DateParameterConverterProvider.class, + SecurityRequestFilter.class, + CorsResponseFilter.class, + ResourceErrorHandler.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); - resourceConfig.register(new GuiceBridgeInitializer(injector)); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } -- cgit v1.2.3 From 0de7889d5548ab16bc8dc31e8734dc48dd51d43d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 18:11:36 -0700 Subject: Better Jersey injection --- .../java/org/traccar/api/ObjectMapperProvider.java | 2 + .../api/security/SecurityRequestFilter.java | 19 +++++--- .../org/traccar/web/GuiceBridgeInitializer.java | 49 --------------------- .../traccar/web/WebInjectionManagerFactory.java | 50 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 4 +- ....jersey.internal.inject.InjectionManagerFactory | 1 + 6 files changed, 67 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/org/traccar/web/GuiceBridgeInitializer.java create mode 100644 src/main/java/org/traccar/web/WebInjectionManagerFactory.java create mode 100644 src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java index 4d8b266fa..d63a4b9b0 100644 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -17,12 +17,14 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; +import javax.inject.Inject; import javax.ws.rs.ext.ContextResolver; public class ObjectMapperProvider implements ContextResolver { private final ObjectMapper objectMapper; + @Inject public ObjectMapperProvider(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index ad45dc112..3413175c8 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -17,7 +17,6 @@ package org.traccar.api.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.api.resource.SessionResource; import org.traccar.database.LoginService; import org.traccar.database.StatisticsManager; @@ -26,11 +25,13 @@ import org.traccar.model.User; import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import java.lang.reflect.Method; @@ -55,12 +56,18 @@ public class SecurityRequestFilter implements ContainerRequestFilter { return null; } - @javax.ws.rs.core.Context + @Context private HttpServletRequest request; - @javax.ws.rs.core.Context + @Context private ResourceInfo resourceInfo; + @Inject + private LoginService loginService; + + @Inject + private StatisticsManager statisticsManager; + @Override public void filter(ContainerRequestContext requestContext) { @@ -77,9 +84,9 @@ public class SecurityRequestFilter implements ContainerRequestFilter { try { String[] auth = decodeBasicAuth(authHeader); - User user = Main.getInjector().getInstance(LoginService.class).login(auth[0], auth[1]); + User user = loginService.login(auth[0], auth[1]); if (user != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); + statisticsManager.registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); } } catch (StorageException e) { @@ -90,7 +97,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); + statisticsManager.registerRequest(userId); securityContext = new UserSecurityContext(new UserPrincipal(userId)); } diff --git a/src/main/java/org/traccar/web/GuiceBridgeInitializer.java b/src/main/java/org/traccar/web/GuiceBridgeInitializer.java deleted file mode 100644 index fc9c88f3b..000000000 --- a/src/main/java/org/traccar/web/GuiceBridgeInitializer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.web; - -import com.google.inject.Injector; -import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager; -import org.glassfish.jersey.server.spi.Container; -import org.glassfish.jersey.server.spi.ContainerLifecycleListener; -import org.jvnet.hk2.guice.bridge.api.GuiceBridge; -import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; - -public class GuiceBridgeInitializer implements ContainerLifecycleListener { - - private final Injector injector; - - public GuiceBridgeInitializer(Injector injector) { - this.injector = injector; - } - - @Override - public void onStartup(Container container) { - var injectionManager = container.getApplicationHandler().getInjectionManager(); - var serviceLocator = ((ImmediateHk2InjectionManager) injectionManager).getServiceLocator(); - GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); - var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); - guiceBridge.bridgeGuiceInjector(injector); - } - - @Override - public void onReload(Container container) { - } - - @Override - public void onShutdown(Container container) { - } -} diff --git a/src/main/java/org/traccar/web/WebInjectionManagerFactory.java b/src/main/java/org/traccar/web/WebInjectionManagerFactory.java new file mode 100644 index 000000000..14d9d3dbc --- /dev/null +++ b/src/main/java/org/traccar/web/WebInjectionManagerFactory.java @@ -0,0 +1,50 @@ +/* + * 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.web; + +import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.jersey.inject.hk2.Hk2InjectionManagerFactory; +import org.glassfish.jersey.internal.inject.InjectionManager; +import org.glassfish.jersey.internal.inject.InjectionManagerFactory; +import org.jvnet.hk2.guice.bridge.api.GuiceBridge; +import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; +import org.traccar.Main; + +import javax.annotation.Priority; + +@Priority(20) +public class WebInjectionManagerFactory implements InjectionManagerFactory { + + private final InjectionManagerFactory originalFactory = new Hk2InjectionManagerFactory(); + + private InjectionManager injectGuiceBridge(InjectionManager injectionManager) { + var serviceLocator = injectionManager.getInstance(ServiceLocator.class); + GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); + var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); + guiceBridge.bridgeGuiceInjector(Main.getInjector()); + return injectionManager; + } + + @Override + public InjectionManager create() { + return injectGuiceBridge(originalFactory.create()); + } + + @Override + public InjectionManager create(Object parent) { + return injectGuiceBridge(originalFactory.create(parent)); + } +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 46e401779..d7276d21f 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,7 +15,6 @@ */ package org.traccar.web; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Injector; import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; @@ -173,10 +172,9 @@ public class WebServer implements LifecycleObject { } ResourceConfig resourceConfig = new ResourceConfig(); - resourceConfig.register(new GuiceBridgeInitializer(injector)); - resourceConfig.register(new ObjectMapperProvider(injector.getInstance(ObjectMapper.class))); resourceConfig.registerClasses( JacksonFeature.class, + ObjectMapperProvider.class, DateParameterConverterProvider.class, SecurityRequestFilter.class, CorsResponseFilter.class, diff --git a/src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory b/src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory new file mode 100644 index 000000000..ce0a70630 --- /dev/null +++ b/src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory @@ -0,0 +1 @@ +org.traccar.web.WebInjectionManagerFactory -- cgit v1.2.3 From ee9abd94265eb704b5f5dd2262f1a3460bbe2a8f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 18:19:57 -0700 Subject: Refactor config usage --- src/main/java/org/traccar/MainModule.java | 6 +----- .../java/org/traccar/storage/DatabaseStorage.java | 21 +++++++++++++-------- src/main/java/org/traccar/storage/QueryBuilder.java | 17 ++++++++++------- src/main/java/org/traccar/web/ConsoleServlet.java | 16 +++++++++++----- src/main/java/org/traccar/web/WebServer.java | 2 +- 5 files changed, 36 insertions(+), 26 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index aac11e619..a29c2c910 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -88,6 +88,7 @@ public class MainModule extends AbstractModule { @Override protected void configure() { + bind(Storage.class).to(DatabaseStorage.class); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } @@ -108,11 +109,6 @@ public class MainModule extends AbstractModule { return Context.getConfig(); } - @Provides - public static Storage provideStorage(DataSource dataSource, ObjectMapper objectMapper) { - return new DatabaseStorage(dataSource, objectMapper); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 661e792d4..052f11ad2 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -16,6 +16,7 @@ package org.traccar.storage; import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.config.Config; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; @@ -27,6 +28,7 @@ import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.sql.DataSource; import java.sql.SQLException; import java.util.HashMap; @@ -38,10 +40,13 @@ import java.util.stream.Collectors; public class DatabaseStorage extends Storage { + private final Config config; private final DataSource dataSource; private final ObjectMapper objectMapper; - public DatabaseStorage(DataSource dataSource, ObjectMapper objectMapper) { + @Inject + public DatabaseStorage(Config config, DataSource dataSource, ObjectMapper objectMapper) { + this.config = config; this.dataSource = dataSource; this.objectMapper = objectMapper; } @@ -55,7 +60,7 @@ public class DatabaseStorage extends Storage { query.append(formatOrder(request.getOrder())); query.append(formatLimit(request.getLimit())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -75,7 +80,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> ':' + c)); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); builder.setObject(entity); return builder.executeUpdate(); } catch (SQLException e) { @@ -91,7 +96,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); builder.setObject(entity); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); @@ -108,7 +113,7 @@ public class DatabaseStorage extends Storage { query.append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -136,7 +141,7 @@ public class DatabaseStorage extends Storage { Condition combinedCondition = Condition.merge(conditions); query.append(formatCondition(combinedCondition)); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(combinedCondition).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -154,7 +159,7 @@ public class DatabaseStorage extends Storage { query.append(permission.get().keySet().stream().map(key -> ':' + key).collect(Collectors.joining(", "))); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } @@ -172,7 +177,7 @@ public class DatabaseStorage extends Storage { query.append(permission .get().keySet().stream().map(key -> key + " = :" + key).collect(Collectors.joining(" AND "))); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 8502d5f0b..910ebf170 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Permission; @@ -42,10 +42,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +@SuppressWarnings("UnusedReturnValue") public final class QueryBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class); + private final Config config; private final ObjectMapper objectMapper; private final Map> indexMap = new HashMap<>(); @@ -55,8 +57,9 @@ public final class QueryBuilder { private final boolean returnGeneratedKeys; private QueryBuilder( - DataSource dataSource, ObjectMapper objectMapper, + Config config, DataSource dataSource, ObjectMapper objectMapper, String query, boolean returnGeneratedKeys) throws SQLException { + this.config = config; this.objectMapper = objectMapper; this.query = query; this.returnGeneratedKeys = returnGeneratedKeys; @@ -133,14 +136,14 @@ public final class QueryBuilder { } public static QueryBuilder create( - DataSource dataSource, ObjectMapper objectMapper, String query) throws SQLException { - return new QueryBuilder(dataSource, objectMapper, query, false); + Config config, DataSource dataSource, ObjectMapper objectMapper, String query) throws SQLException { + return new QueryBuilder(config, dataSource, objectMapper, query, false); } public static QueryBuilder create( - DataSource dataSource, ObjectMapper objectMapper, String query, + Config config, DataSource dataSource, ObjectMapper objectMapper, String query, boolean returnGeneratedKeys) throws SQLException { - return new QueryBuilder(dataSource, objectMapper, query, returnGeneratedKeys); + return new QueryBuilder(config, dataSource, objectMapper, query, returnGeneratedKeys); } private List indexes(String name) { @@ -396,7 +399,7 @@ public final class QueryBuilder { } private void logQuery() { - if (Context.getConfig().getBoolean(Keys.LOGGER_QUERIES)) { + if (config.getBoolean(Keys.LOGGER_QUERIES)) { LOGGER.info(query); } } diff --git a/src/main/java/org/traccar/web/ConsoleServlet.java b/src/main/java/org/traccar/web/ConsoleServlet.java index 0f3dcd8fd..902a4f7a9 100644 --- a/src/main/java/org/traccar/web/ConsoleServlet.java +++ b/src/main/java/org/traccar/web/ConsoleServlet.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. @@ -19,7 +19,7 @@ import org.h2.server.web.ConnectionInfo; import org.h2.server.web.WebServlet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.lang.reflect.Field; @@ -30,6 +30,12 @@ public class ConsoleServlet extends WebServlet { private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleServlet.class); + private final Config config; + + public ConsoleServlet(Config config) { + this.config = config; + } + @Override public void init() { super.init(); @@ -40,9 +46,9 @@ public class ConsoleServlet extends WebServlet { org.h2.server.web.WebServer server = (org.h2.server.web.WebServer) field.get(this); ConnectionInfo connectionInfo = new ConnectionInfo("Traccar|" - + Context.getConfig().getString(Keys.DATABASE_DRIVER) + "|" - + Context.getConfig().getString(Keys.DATABASE_URL) + "|" - + Context.getConfig().getString(Keys.DATABASE_USER)); + + config.getString(Keys.DATABASE_DRIVER) + "|" + + config.getString(Keys.DATABASE_URL) + "|" + + config.getString(Keys.DATABASE_USER)); Method method; diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index d7276d21f..6c8a798b4 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -91,7 +91,7 @@ public class WebServer implements LifecycleObject { initSessionConfig(servletHandler); if (config.getBoolean(Keys.WEB_CONSOLE)) { - servletHandler.addServlet(new ServletHolder(new ConsoleServlet()), "/console/*"); + servletHandler.addServlet(new ServletHolder(new ConsoleServlet(config)), "/console/*"); } initWebApp(servletHandler); -- cgit v1.2.3 From 15c4b6b21a31c63bc0f7e624e26d032d531c459d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 18:48:08 -0700 Subject: Refactor geofence classes --- src/main/java/org/traccar/MainModule.java | 1 - .../java/org/traccar/geofence/GeofenceCircle.java | 4 +- .../org/traccar/geofence/GeofenceGeometry.java | 5 ++- .../java/org/traccar/geofence/GeofencePolygon.java | 4 +- .../org/traccar/geofence/GeofencePolyline.java | 23 +++++------ .../handler/events/GeofenceEventHandler.java | 7 +++- .../org/traccar/helper/model/GeofenceUtil.java | 6 ++- src/main/java/org/traccar/model/Geofence.java | 22 ++++------- .../org/traccar/session/cache/CacheManager.java | 7 +++- .../org/traccar/geofence/GeofenceCircleTest.java | 13 +++--- .../org/traccar/geofence/GeofencePolygonTest.java | 37 +++++++---------- .../org/traccar/geofence/GeofencePolylineTest.java | 46 ++++++++++++++-------- 12 files changed, 93 insertions(+), 82 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a29c2c910..a9337a3a2 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -75,7 +75,6 @@ import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; -import javax.sql.DataSource; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; diff --git a/src/main/java/org/traccar/geofence/GeofenceCircle.java b/src/main/java/org/traccar/geofence/GeofenceCircle.java index 5d566f84e..59feb1730 100644 --- a/src/main/java/org/traccar/geofence/GeofenceCircle.java +++ b/src/main/java/org/traccar/geofence/GeofenceCircle.java @@ -18,7 +18,9 @@ package org.traccar.geofence; import java.text.DecimalFormat; import java.text.ParseException; +import org.traccar.config.Config; import org.traccar.helper.DistanceCalculator; +import org.traccar.model.Geofence; public class GeofenceCircle extends GeofenceGeometry { @@ -44,7 +46,7 @@ public class GeofenceCircle extends GeofenceGeometry { } @Override - public boolean containsPoint(double latitude, double longitude) { + public boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude) { return distanceFromCenter(latitude, longitude) <= radius; } diff --git a/src/main/java/org/traccar/geofence/GeofenceGeometry.java b/src/main/java/org/traccar/geofence/GeofenceGeometry.java index 2c45c22af..fadabab1c 100644 --- a/src/main/java/org/traccar/geofence/GeofenceGeometry.java +++ b/src/main/java/org/traccar/geofence/GeofenceGeometry.java @@ -15,11 +15,14 @@ */ package org.traccar.geofence; +import org.traccar.config.Config; +import org.traccar.model.Geofence; + import java.text.ParseException; public abstract class GeofenceGeometry { - public abstract boolean containsPoint(double latitude, double longitude); + public abstract boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude); public abstract double calculateArea(); diff --git a/src/main/java/org/traccar/geofence/GeofencePolygon.java b/src/main/java/org/traccar/geofence/GeofencePolygon.java index cd2cbf16a..13f6658ef 100644 --- a/src/main/java/org/traccar/geofence/GeofencePolygon.java +++ b/src/main/java/org/traccar/geofence/GeofencePolygon.java @@ -19,6 +19,8 @@ import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory; import org.locationtech.spatial4j.shape.ShapeFactory; import org.locationtech.spatial4j.shape.jts.JtsShapeFactory; +import org.traccar.config.Config; +import org.traccar.model.Geofence; import java.text.ParseException; import java.util.ArrayList; @@ -95,7 +97,7 @@ public class GeofencePolygon extends GeofenceGeometry { } @Override - public boolean containsPoint(double latitude, double longitude) { + public boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude) { int polyCorners = coordinates.size(); int i; diff --git a/src/main/java/org/traccar/geofence/GeofencePolyline.java b/src/main/java/org/traccar/geofence/GeofencePolyline.java index 370bf99bb..d9c280ae4 100644 --- a/src/main/java/org/traccar/geofence/GeofencePolyline.java +++ b/src/main/java/org/traccar/geofence/GeofencePolyline.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 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"); @@ -19,23 +19,28 @@ package org.traccar.geofence; import java.text.ParseException; import java.util.ArrayList; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.DistanceCalculator; +import org.traccar.model.Geofence; public class GeofencePolyline extends GeofenceGeometry { private ArrayList coordinates; - private double distance; public GeofencePolyline() { } - public GeofencePolyline(String wkt, double distance) throws ParseException { + public GeofencePolyline(String wkt) throws ParseException { fromWkt(wkt); - this.distance = distance; } @Override - public boolean containsPoint(double latitude, double longitude) { + public boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude) { + double distance = geofence.getDouble("polylineDistance"); + if (distance == 0) { + distance = config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE); + } for (int i = 1; i < coordinates.size(); i++) { if (DistanceCalculator.distanceToLine( latitude, longitude, coordinates.get(i - 1).getLat(), coordinates.get(i - 1).getLon(), @@ -56,9 +61,9 @@ public class GeofencePolyline extends GeofenceGeometry { StringBuilder buf = new StringBuilder(); buf.append("LINESTRING ("); for (Coordinate coordinate : coordinates) { - buf.append(String.valueOf(coordinate.getLat())); + buf.append(coordinate.getLat()); buf.append(" "); - buf.append(String.valueOf(coordinate.getLon())); + buf.append(coordinate.getLon()); buf.append(", "); } return buf.substring(0, buf.length() - 2) + ")"; @@ -105,8 +110,4 @@ public class GeofencePolyline extends GeofenceGeometry { } - public void setDistance(double distance) { - this.distance = distance; - } - } diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 724f8f0d0..0a924cfc3 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -16,6 +16,7 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; +import org.traccar.config.Config; import org.traccar.helper.model.GeofenceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Calendar; @@ -35,11 +36,13 @@ import java.util.Map; @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { + private final Config config; private final CacheManager cacheManager; private final ConnectionManager connectionManager; @Inject - public GeofenceEventHandler(CacheManager cacheManager, ConnectionManager connectionManager) { + public GeofenceEventHandler(Config config, CacheManager cacheManager, ConnectionManager connectionManager) { + this.config = config; this.cacheManager = cacheManager; this.connectionManager = connectionManager; } @@ -54,7 +57,7 @@ public class GeofenceEventHandler extends BaseEventHandler { return null; } - List currentGeofences = GeofenceUtil.getCurrentGeofences(cacheManager, position); + List currentGeofences = GeofenceUtil.getCurrentGeofences(config, cacheManager, position); List oldGeofences = new ArrayList<>(); if (device.getGeofenceIds() != null) { oldGeofences.addAll(device.getGeofenceIds()); diff --git a/src/main/java/org/traccar/helper/model/GeofenceUtil.java b/src/main/java/org/traccar/helper/model/GeofenceUtil.java index f56bf4224..9f063a8b4 100644 --- a/src/main/java/org/traccar/helper/model/GeofenceUtil.java +++ b/src/main/java/org/traccar/helper/model/GeofenceUtil.java @@ -15,6 +15,7 @@ */ package org.traccar.helper.model; +import org.traccar.config.Config; import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; @@ -27,10 +28,11 @@ public final class GeofenceUtil { private GeofenceUtil() { } - public static List getCurrentGeofences(CacheManager cacheManager, Position position) { + public static List getCurrentGeofences(Config config, CacheManager cacheManager, Position position) { List result = new ArrayList<>(); for (Geofence geofence : cacheManager.getDeviceObjects(position.getDeviceId(), Geofence.class)) { - if (geofence.getGeometry().containsPoint(position.getLatitude(), position.getLongitude())) { + if (geofence.getGeometry().containsPoint( + config, geofence, position.getLatitude(), position.getLongitude())) { result.add(geofence.getId()); } } diff --git a/src/main/java/org/traccar/model/Geofence.java b/src/main/java/org/traccar/model/Geofence.java index 5b857580d..9259028fb 100644 --- a/src/main/java/org/traccar/model/Geofence.java +++ b/src/main/java/org/traccar/model/Geofence.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. @@ -15,26 +15,19 @@ */ package org.traccar.model; -import java.text.ParseException; - -import org.traccar.Context; -import org.traccar.config.Keys; -import org.traccar.storage.QueryIgnore; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.geofence.GeofenceCircle; import org.traccar.geofence.GeofenceGeometry; import org.traccar.geofence.GeofencePolygon; import org.traccar.geofence.GeofencePolyline; - -import com.fasterxml.jackson.annotation.JsonIgnore; +import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; +import java.text.ParseException; + @StorageName("tc_geofences") public class Geofence extends ScheduledModel { - public static final String TYPE_GEOFENCE_CILCLE = "geofenceCircle"; - public static final String TYPE_GEOFENCE_POLYGON = "geofencePolygon"; - public static final String TYPE_GEOFENCE_POLYLINE = "geofencePolyline"; - private String name; public String getName() { @@ -68,9 +61,7 @@ public class Geofence extends ScheduledModel { } else if (area.startsWith("POLYGON")) { geometry = new GeofencePolygon(area); } else if (area.startsWith("LINESTRING")) { - final double distance = getDouble("polylineDistance"); - geometry = new GeofencePolyline(area, distance > 0 ? distance - : Context.getConfig().getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)); + geometry = new GeofencePolyline(area); } else { throw new ParseException("Unknown geometry type", 0); } @@ -92,4 +83,5 @@ public class Geofence extends ScheduledModel { area = geometry.toWkt(); this.geometry = geometry; } + } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 18daeae15..14034f3d6 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,7 @@ */ package org.traccar.session.cache; +import org.traccar.config.Config; import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; @@ -53,6 +54,7 @@ public class CacheManager { private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); + private final Config config; private final Storage storage; private final ReadWriteLock lock = new ReentrantReadWriteLock(); @@ -65,7 +67,8 @@ public class CacheManager { private final Map> notificationUsers = new HashMap<>(); @Inject - public CacheManager(Storage storage) throws StorageException { + public CacheManager(Config config, Storage storage) throws StorageException { + this.config = config; this.storage = storage; invalidateServer(); invalidateUsers(); @@ -315,7 +318,7 @@ public class CacheManager { private void invalidateDeviceGeofences(Device device) { Position position = getPosition(device.getId()); if (position != null) { - device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(this, position)); + device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(config, this, position)); } } diff --git a/src/test/java/org/traccar/geofence/GeofenceCircleTest.java b/src/test/java/org/traccar/geofence/GeofenceCircleTest.java index 038e4b6d6..9a02cec76 100644 --- a/src/test/java/org/traccar/geofence/GeofenceCircleTest.java +++ b/src/test/java/org/traccar/geofence/GeofenceCircleTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import java.text.ParseException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class GeofenceCircleTest { @@ -12,17 +13,15 @@ public class GeofenceCircleTest { @Test public void testCircleWkt() throws ParseException { String test = "CIRCLE (55.75414 37.6204, 100)"; - GeofenceGeometry geofenceGeometry = new GeofenceCircle(); - geofenceGeometry.fromWkt(test); + GeofenceGeometry geofenceGeometry = new GeofenceCircle(test); assertEquals(geofenceGeometry.toWkt(), test); } @Test public void testContainsCircle() throws ParseException { - String test = "CIRCLE (55.75414 37.6204, 100)"; - GeofenceGeometry geofenceGeometry = new GeofenceCircle(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(55.75477, 37.62025)); - assertTrue(!geofenceGeometry.containsPoint(55.75545, 37.61921)); + GeofenceGeometry geofenceGeometry = new GeofenceCircle("CIRCLE (55.75414 37.6204, 100)"); + assertTrue(geofenceGeometry.containsPoint(null, null, 55.75477, 37.62025)); + assertFalse(geofenceGeometry.containsPoint(null, null, 55.75545, 37.61921)); } + } diff --git a/src/test/java/org/traccar/geofence/GeofencePolygonTest.java b/src/test/java/org/traccar/geofence/GeofencePolygonTest.java index 1b8de68ad..5baecd771 100644 --- a/src/test/java/org/traccar/geofence/GeofencePolygonTest.java +++ b/src/test/java/org/traccar/geofence/GeofencePolygonTest.java @@ -19,41 +19,34 @@ public class GeofencePolygonTest { @Test public void testPolygonWkt() throws ParseException { String test = "POLYGON ((55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); + GeofenceGeometry geofenceGeometry = new GeofencePolygon(test); assertEquals(geofenceGeometry.toWkt(), test); } @Test public void testContainsPolygon() throws ParseException { - String test = "POLYGON ((55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(55.75476, 37.61915)); - assertFalse(geofenceGeometry.containsPoint(55.75545, 37.61921)); - + GeofenceGeometry geofenceGeometry = new GeofencePolygon( + "POLYGON ((55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165))"); + assertTrue(geofenceGeometry.containsPoint(null, null, 55.75476, 37.61915)); + assertFalse(geofenceGeometry.containsPoint(null, null, 55.75545, 37.61921)); } @Test public void testContainsPolygon180() throws ParseException { - String test = "POLYGON ((66.9494 179.838, 66.9508 -179.8496, 66.8406 -180.0014))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(66.9015, -180.0096)); - assertTrue(geofenceGeometry.containsPoint(66.9015, 179.991)); - assertFalse(geofenceGeometry.containsPoint(66.8368, -179.8792)); - + GeofenceGeometry geofenceGeometry = new GeofencePolygon( + "POLYGON ((66.9494 179.838, 66.9508 -179.8496, 66.8406 -180.0014))"); + assertTrue(geofenceGeometry.containsPoint(null, null, 66.9015, -180.0096)); + assertTrue(geofenceGeometry.containsPoint(null, null, 66.9015, 179.991)); + assertFalse(geofenceGeometry.containsPoint(null, null, 66.8368, -179.8792)); } @Test public void testContainsPolygon0() throws ParseException { - String test = "POLYGON ((51.1966 -0.6207, 51.1897 0.4147, 50.9377 0.5136, 50.8675 -0.6082))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(51.0466, -0.0165)); - assertTrue(geofenceGeometry.containsPoint(51.0466, 0.018)); - assertFalse(geofenceGeometry.containsPoint(50.9477, 0.5836)); - + GeofenceGeometry geofenceGeometry = new GeofencePolygon( + "POLYGON ((51.1966 -0.6207, 51.1897 0.4147, 50.9377 0.5136, 50.8675 -0.6082))"); + assertTrue(geofenceGeometry.containsPoint(null, null, 51.0466, -0.0165)); + assertTrue(geofenceGeometry.containsPoint(null, null, 51.0466, 0.018)); + assertFalse(geofenceGeometry.containsPoint(null, null, 50.9477, 0.5836)); } } diff --git a/src/test/java/org/traccar/geofence/GeofencePolylineTest.java b/src/test/java/org/traccar/geofence/GeofencePolylineTest.java index 0e8905319..b7ee14510 100644 --- a/src/test/java/org/traccar/geofence/GeofencePolylineTest.java +++ b/src/test/java/org/traccar/geofence/GeofencePolylineTest.java @@ -1,47 +1,59 @@ package org.traccar.geofence; import org.junit.Test; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Geofence; import java.text.ParseException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class GeofencePolylineTest { @Test public void testPolylineWkt() throws ParseException { String test = "LINESTRING (55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(); - geofenceGeometry.fromWkt(test); + GeofenceGeometry geofenceGeometry = new GeofencePolyline(test); assertEquals(geofenceGeometry.toWkt(), test); } @Test public void testContainsPolyline1Interval() throws ParseException { - String test = "LINESTRING (56.83777 60.59833, 56.83766 60.5968)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(test, 35); - assertTrue(geofenceGeometry.containsPoint(56.83801, 60.59748)); - ((GeofencePolyline) geofenceGeometry).setDistance(15); - assertTrue(!geofenceGeometry.containsPoint(56.83801, 60.59748)); + GeofenceGeometry geofenceGeometry = new GeofencePolyline( + "LINESTRING (56.83777 60.59833, 56.83766 60.5968)"); + Config config = mock(Config.class); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(35.0); + assertTrue(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83801, 60.59748)); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(15.0); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83801, 60.59748)); } @Test public void testContainsPolyline3Intervals() throws ParseException { - String test = "LINESTRING (56.836 60.6126, 56.8393 60.6114, 56.83887 60.60811, 56.83782 60.5988)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(test, 15); - assertTrue(geofenceGeometry.containsPoint(56.83847, 60.60458)); - assertTrue(!geofenceGeometry.containsPoint(56.83764, 60.59725)); - assertTrue(!geofenceGeometry.containsPoint(56.83861, 60.60822)); + GeofenceGeometry geofenceGeometry = new GeofencePolyline( + "LINESTRING (56.836 60.6126, 56.8393 60.6114, 56.83887 60.60811, 56.83782 60.5988)"); + Config config = mock(Config.class); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(15.0); + assertTrue(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83847, 60.60458)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83764, 60.59725)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83861, 60.60822)); } @Test public void testContainsPolylineNear180() throws ParseException { - String test = "LINESTRING (66.9494 179.838, 66.9508 -179.8496)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(test, 25); - assertTrue(geofenceGeometry.containsPoint(66.95, 180.0)); - assertTrue(!geofenceGeometry.containsPoint(66.96, 180.0)); - assertTrue(!geofenceGeometry.containsPoint(66.9509, -179.83)); + GeofenceGeometry geofenceGeometry = new GeofencePolyline( + "LINESTRING (66.9494 179.838, 66.9508 -179.8496)"); + Config config = mock(Config.class); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(25.0); + assertTrue(geofenceGeometry.containsPoint(config, mock(Geofence.class), 66.95, 180.0)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 66.96, 180.0)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 66.9509, -179.83)); } + } -- cgit v1.2.3 From 316ef36ca8bf6425df5a6186da2e7901dcb23c0e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 17 Jun 2022 17:20:11 -0700 Subject: Fix caching issues --- src/main/java/org/traccar/session/ConnectionManager.java | 2 +- src/main/java/org/traccar/session/cache/CacheManager.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index c8c07f9c7..6d5fefa75 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -128,7 +128,7 @@ public class ConnectionManager { if (oldSession != null) { Endpoint oldEndpoint = new Endpoint(oldSession.getChannel(), oldSession.getRemoteAddress()); Map oldEndpointSessions = sessionsByEndpoint.get(oldEndpoint); - if (oldEndpointSessions.size() > 1) { + if (oldEndpointSessions != null && oldEndpointSessions.size() > 1) { oldEndpointSessions.remove(device.getUniqueId()); } else { sessionsByEndpoint.remove(oldEndpoint); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 14034f3d6..896df83e7 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -245,6 +245,7 @@ public class CacheManager { new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); for (var user : users) { + addObject(deviceId, user); var notifications = storage.getObjects(Notification.class, new Request( new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); notifications.stream() -- cgit v1.2.3 From 9fa2fc7091041a5cffa9092318d5d2f5a1a367a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 07:35:32 -0700 Subject: Migrate device resource --- .../org/traccar/api/resource/DeviceResource.java | 101 ++++++++++++++------- .../java/org/traccar/database/DeviceManager.java | 43 +++------ .../org/traccar/database/PermissionsManager.java | 11 --- 3 files changed, 80 insertions(+), 75 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index cd5ebf0c5..2509c9003 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.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. @@ -15,13 +15,18 @@ */ package org.traccar.api.resource; -import org.traccar.Context; +import org.traccar.Main; import org.traccar.api.BaseObjectResource; -import org.traccar.database.DeviceManager; import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; +import org.traccar.model.Position; +import org.traccar.model.User; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -32,9 +37,8 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Collection; -import java.util.HashSet; +import java.util.LinkedList; import java.util.List; -import java.util.Set; @Path("devices") @Produces(MediaType.APPLICATION_JSON) @@ -50,38 +54,46 @@ public class DeviceResource extends BaseObjectResource { @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("uniqueId") List uniqueIds, @QueryParam("id") List deviceIds) throws StorageException { - DeviceManager deviceManager = Context.getDeviceManager(); - Set result; - if (all) { - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = deviceManager.getAllItems(); - } else { - Context.getPermissionsManager().checkManager(getUserId()); - result = deviceManager.getUserItems(getUserId()); - } - } else if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { - if (userId == 0) { - userId = getUserId(); - } - permissionsService.checkUser(getUserId(), userId); - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = deviceManager.getAllUserItems(userId); - } else { - result = deviceManager.getUserItems(userId); - } - } else { - result = new HashSet<>(); + + if (!uniqueIds.isEmpty() || !deviceIds.isEmpty()) { + + List result = new LinkedList<>(); for (String uniqueId : uniqueIds) { - Device device = deviceManager.getByUniqueId(uniqueId); - permissionsService.checkPermission(Device.class, getUserId(), device.getId()); - result.add(device.getId()); + result.addAll(storage.getObjects(Device.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("uniqueId", "uniqueId", uniqueId), + new Condition.Permission(User.class, getUserId(), Device.class))))); } for (Long deviceId : deviceIds) { - permissionsService.checkPermission(Device.class, getUserId(), deviceId); - result.add(deviceId); + result.addAll(storage.getObjects(Device.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("id", "id", deviceId), + new Condition.Permission(User.class, getUserId(), Device.class))))); + } + return result; + + } else { + + var conditions = new LinkedList(); + + if (all) { + if (permissionsService.notAdmin(getUserId())) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } + } else { + if (userId == 0) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } else { + permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, userId, baseClass).excludeGroups()); + } } + + return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); + } - return deviceManager.getItems(result); } @Path("{id}/accumulators") @@ -91,7 +103,30 @@ public class DeviceResource extends BaseObjectResource { permissionsService.checkManager(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); } - Context.getDeviceManager().resetDeviceAccumulators(entity); + + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions(entity.getDeviceId()))); + if (position != null) { + if (entity.getTotalDistance() != null) { + position.getAttributes().put(Position.KEY_TOTAL_DISTANCE, entity.getTotalDistance()); + } + if (entity.getHours() != null) { + position.getAttributes().put(Position.KEY_HOURS, entity.getHours()); + } + position.setId(storage.addObject(position, new Request(new Columns.Exclude("id")))); + + Device device = new Device(); + device.setId(position.getDeviceId()); + device.setPositionId(position.getId()); + storage.updateObject(device, new Request( + new Columns.Include("positionId"), + new Condition.Equals("id", "id"))); + + Main.getInjector().getInstance(CacheManager.class).updatePosition(position); + } else { + throw new IllegalArgumentException(); + } + LogAction.resetDeviceAccumulators(getUserId(), entity.getDeviceId()); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index bd100245c..81043fd7a 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,32 +15,30 @@ */ package org.traccar.database; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; -import org.traccar.config.Config; import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; -import org.traccar.session.ConnectionManager; -import org.traccar.session.DeviceState; -import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; +import org.traccar.session.ConnectionManager; +import org.traccar.session.DeviceState; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + public class DeviceManager extends BaseObjectManager implements IdentityManager { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); @@ -378,23 +376,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result; } - public void resetDeviceAccumulators(DeviceAccumulators deviceAccumulators) throws StorageException { - Position last = positions.get(deviceAccumulators.getDeviceId()); - if (last != null) { - if (deviceAccumulators.getTotalDistance() != null) { - last.getAttributes().put(Position.KEY_TOTAL_DISTANCE, deviceAccumulators.getTotalDistance()); - } - if (deviceAccumulators.getHours() != null) { - last.getAttributes().put(Position.KEY_HOURS, deviceAccumulators.getHours()); - } - getDataManager().addObject(last); - updateLatestPosition(last); - Main.getInjector().getInstance(CacheManager.class).updatePosition(last); - } else { - throw new IllegalArgumentException(); - } - } - public DeviceState getDeviceState(long deviceId) { DeviceState deviceState = deviceStates.get(deviceId); if (deviceState == null) { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 4ac27c717..9d1e5aadf 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -179,17 +179,6 @@ public class PermissionsManager { return user != null && user.getAdministrator(); } - public boolean getUserManager(long userId) { - User user = getUser(userId); - return user != null && user.getUserLimit() != 0; - } - - public void checkManager(long userId) throws SecurityException { - if (!getUserManager(userId)) { - throw new SecurityException("Manager access required"); - } - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) -- cgit v1.2.3 From 68826cdc767bae6b8b39e88667372f0c6161efa9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 07:40:47 -0700 Subject: Rename key type --- src/main/java/org/traccar/config/KeyType.java | 2 +- src/main/java/org/traccar/config/Keys.java | 348 +++++++++++++------------- 2 files changed, 175 insertions(+), 175 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/KeyType.java b/src/main/java/org/traccar/config/KeyType.java index 57a95c9ec..46628f9fc 100644 --- a/src/main/java/org/traccar/config/KeyType.java +++ b/src/main/java/org/traccar/config/KeyType.java @@ -16,7 +16,7 @@ package org.traccar.config; public enum KeyType { - GLOBAL, + CONFIG, SERVER, USER, DEVICE, diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 82afe048b..292202de0 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -27,7 +27,7 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_ADDRESS = new ConfigSuffix<>( ".address", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Port number for the protocol. Most protocols use TCP on the transport layer. Some protocols use UDP. Some @@ -35,7 +35,7 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_PORT = new ConfigSuffix<>( ".port", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * List of devices for polling protocols. List should contain unique ids separated by commas. Used only for polling @@ -43,21 +43,21 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_DEVICES = new ConfigSuffix<>( ".devices", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Polling interval in seconds. Used only for polling protocols. */ public static final ConfigSuffix PROTOCOL_INTERVAL = new ConfigSuffix<>( ".interval", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable SSL support for the protocol. Not all protocols support this. */ public static final ConfigSuffix PROTOCOL_SSL = new ConfigSuffix<>( ".ssl", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Connection timeout value in seconds. Because sometimes there is no way to detect lost TCP connection old @@ -67,28 +67,28 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_TIMEOUT = new ConfigSuffix<>( ".timeout", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Device password. Commonly used in some protocol for sending commands. */ public static final ConfigSuffix PROTOCOL_DEVICE_PASSWORD = new ConfigSuffix<>( ".devicePassword", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default protocol mask to use. Currently used only by Skypatrol protocol. */ public static final ConfigSuffix PROTOCOL_MASK = new ConfigSuffix<>( ".mask", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Custom message length. Currently used only by H2 protocol for specifying binary message length. */ public static final ConfigSuffix PROTOCOL_MESSAGE_LENGTH = new ConfigSuffix<>( ".messageLength", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable extended functionality for the protocol. The reason it's disabled by default is that not all devices @@ -96,28 +96,28 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_EXTENDED = new ConfigSuffix<>( ".extended", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Decode string as UTF8 instead of ASCII. Only applicable for some protocols. */ public static final ConfigSuffix PROTOCOL_UTF8 = new ConfigSuffix<>( ".utf8", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable CAN decoding for the protocol. Similar to 'extended' configuration, it's not supported for some devices. */ public static final ConfigSuffix PROTOCOL_CAN = new ConfigSuffix<>( ".can", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Indicates whether server acknowledgement is required. Only applicable for some protocols. */ public static final ConfigSuffix PROTOCOL_ACK = new ConfigSuffix<>( ".ack", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Ignore device reported fix time. Useful in case some devices report invalid time. Currently only available for @@ -125,91 +125,91 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_IGNORE_FIX_TIME = new ConfigSuffix<>( ".ignoreFixTime", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Decode additional TK103 attributes. Not supported for some devices. */ public static final ConfigSuffix PROTOCOL_DECODE_LOW = new ConfigSuffix<>( ".decodeLow", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Use long date format for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_LONG_DATE = new ConfigSuffix<>( ".longDate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Use decimal fuel value format for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_DECIMAL_FUEL = new ConfigSuffix<>( ".decimalFuel", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Indicates additional custom attributes for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_CUSTOM = new ConfigSuffix<>( ".custom", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Custom format string for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_FORM = new ConfigSuffix<>( ".form", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Protocol configuration. Required for some devices for decoding incoming data. */ public static final ConfigSuffix PROTOCOL_CONFIG = new ConfigSuffix<>( ".config", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Alarm mapping for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_ALARM_MAP = new ConfigSuffix<>( ".alarmMap", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Indicates whether TAIP protocol should have prefixes for messages. */ public static final ConfigSuffix PROTOCOL_PREFIX = new ConfigSuffix<>( ".prefix", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Some devices require server address confirmation. Use this parameter to configure correct public address. */ public static final ConfigSuffix PROTOCOL_SERVER = new ConfigSuffix<>( ".server", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * ORBCOMM API access id. */ public static final ConfigKey ORBCOMM_ACCESS_ID = new ConfigKey<>( "orbcomm.accessId", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * ORBCOMM API password. */ public static final ConfigKey ORBCOMM_PASSWORD = new ConfigKey<>( "orbcomm.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ public static final ConfigKey SERVER_TIMEOUT = new ConfigKey<>( "server.timeout", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Address for uploading aggregated anonymous usage statistics. Uploaded information is the same you can see on the @@ -217,63 +217,63 @@ public final class Keys { */ public static final ConfigKey SERVER_STATISTICS = new ConfigKey<>( "server.statistics", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If true, the event is generated once at the beginning of overspeeding period. */ public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new ConfigKey<>( "event.overspeed.notRepeat", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Minimal over speed duration to trigger the event. Value in seconds. */ public static final ConfigKey EVENT_OVERSPEED_MINIMAL_DURATION = new ConfigKey<>( "event.overspeed.minimalDuration", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Relevant only for geofence speed limits. Use the lowest speed limit from all geofences. */ public static final ConfigKey EVENT_OVERSPEED_PREFER_LOWEST = new ConfigKey<>( "event.overspeed.preferLowest", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Driver behavior acceleration threshold. Value is in meter per second squared. */ public static final ConfigKey EVENT_BEHAVIOR_ACCELERATION_THRESHOLD = new ConfigKey<>( "event.behavior.accelerationThreshold", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Driver behavior braking threshold. Value is in meter per second squared. */ public static final ConfigKey EVENT_BEHAVIOR_BRAKING_THRESHOLD = new ConfigKey<>( "event.behavior.brakingThreshold", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Do not generate alert event if same alert was present in last known location. */ public static final ConfigKey EVENT_IGNORE_DUPLICATE_ALERTS = new ConfigKey<>( "event.ignoreDuplicateAlerts", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If set to true, invalid positions will be considered for motion logic. */ public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( "event.motion.processInvalidPositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If the speed is above specified value, the object is considered to be in motion. Default value is 0.01 knots. */ public static final ConfigKey EVENT_MOTION_SPEED_THRESHOLD = new ConfigKey<>( "event.motion.speedThreshold", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 0.01); /** @@ -282,7 +282,7 @@ public final class Keys { */ public static final ConfigKey GEOFENCE_POLYLINE_DISTANCE = new ConfigKey<>( "geofence.polylineDistance", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 25.0); /** @@ -291,49 +291,49 @@ public final class Keys { */ public static final ConfigKey DATABASE_DRIVER_FILE = new ConfigKey<>( "database.driverFile", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database driver Java class. For H2 use 'org.h2.Driver'. MySQL driver class name is 'com.mysql.jdbc.Driver'. */ public static final ConfigKey DATABASE_DRIVER = new ConfigKey<>( "database.driver", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database connection URL. By default Traccar uses H2 database. */ public static final ConfigKey DATABASE_URL = new ConfigKey<>( "database.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database user name. Default administrator user for H2 database is 'sa'. */ public static final ConfigKey DATABASE_USER = new ConfigKey<>( "database.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database user password. Default password for H2 admin (sa) user is empty. */ public static final ConfigKey DATABASE_PASSWORD = new ConfigKey<>( "database.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Path to Liquibase master changelog file. */ public static final ConfigKey DATABASE_CHANGELOG = new ConfigKey<>( "database.changelog", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database connection pool size. Default value is defined by the HikariCP library. */ public static final ConfigKey DATABASE_MAX_POOL_SIZE = new ConfigKey<>( "database.maxPoolSize", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SQL query to check connection status. Default value is 'SELECT 1'. For Oracle database you can use @@ -341,7 +341,7 @@ public final class Keys { */ public static final ConfigKey DATABASE_CHECK_CONNECTION = new ConfigKey<>( "database.checkConnection", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "SELECT 1"); /** @@ -349,7 +349,7 @@ public final class Keys { */ public static final ConfigKey DATABASE_SAVE_ORIGINAL = new ConfigKey<>( "database.saveOriginal", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * By default server syncs with the database if it encounters and unknown device. This flag allows to disable that @@ -357,35 +357,35 @@ public final class Keys { */ public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new ConfigKey<>( "database.ignoreUnknown", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Automatically register unknown devices in the database. */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN = new ConfigKey<>( "database.registerUnknown", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default category for auto-registered devices. */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY = new ConfigKey<>( "database.registerUnknown.defaultCategory", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * The group id assigned to auto-registered devices. */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID = new ConfigKey<>( "database.registerUnknown.defaultGroupId", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Minimum device refresh timeout in seconds. Default timeout is 5 minutes. */ public static final ConfigKey DATABASE_REFRESH_DELAY = new ConfigKey<>( "database.refreshDelay", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 300L); /** @@ -393,14 +393,14 @@ public final class Keys { */ public static final ConfigKey DATABASE_SAVE_EMPTY = new ConfigKey<>( "database.saveEmpty", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Device limit for self registered users. Default value is -1, which indicates no limit. */ public static final ConfigKey USERS_DEFAULT_DEVICE_LIMIT = new ConfigKey<>( "users.defaultDeviceLimit", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), -1); /** @@ -408,49 +408,49 @@ public final class Keys { */ public static final ConfigKey USERS_DEFAULT_EXPIRATION_DAYS = new ConfigKey<>( "users.defaultExpirationDays", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP server URL. */ public static final ConfigKey LDAP_URL = new ConfigKey<>( "ldap.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP server login. */ public static final ConfigKey LDAP_USER = new ConfigKey<>( "ldap.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP server password. */ public static final ConfigKey LDAP_PASSWORD = new ConfigKey<>( "ldap.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Force LDAP authentication. */ public static final ConfigKey LDAP_FORCE = new ConfigKey<>( "ldap.force", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP user search base. */ public static final ConfigKey LDAP_BASE = new ConfigKey<>( "ldap.base", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP attribute used as user id. Default value is 'uid'. */ public static final ConfigKey LDAP_ID_ATTRIBUTE = new ConfigKey<>( "ldap.idAttribute", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "uid"); /** @@ -458,7 +458,7 @@ public final class Keys { */ public static final ConfigKey LDAP_NAME_ATTRIBUTE = new ConfigKey<>( "ldap.nameAttribute", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "cn"); /** @@ -466,7 +466,7 @@ public final class Keys { */ public static final ConfigKey LDAP_MAIN_ATTRIBUTE = new ConfigKey<>( "ldap.mailAttribute", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "mail"); /** @@ -474,21 +474,21 @@ public final class Keys { */ public static final ConfigKey LDAP_SEARCH_FILTER = new ConfigKey<>( "ldap.searchFilter", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP custom admin search filter. */ public static final ConfigKey LDAP_ADMIN_FILTER = new ConfigKey<>( "ldap.adminFilter", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP admin user group. Used if custom admin filter is not specified. */ public static final ConfigKey LDAP_ADMIN_GROUP = new ConfigKey<>( "ldap.adminGroup", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If no data is reported by a device for the given amount of time, status changes from online to unknown. Value is @@ -496,7 +496,7 @@ public final class Keys { */ public static final ConfigKey STATUS_TIMEOUT = new ConfigKey<>( "status.timeout", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 600L); /** @@ -504,7 +504,7 @@ public final class Keys { */ public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new ConfigKey<>( "status.updateDeviceState", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * List of protocol names to ignore offline status. Can be useful to not trigger status change when devices are @@ -512,7 +512,7 @@ public final class Keys { */ public static final ConfigKey STATUS_IGNORE_OFFLINE = new ConfigKey<>( "status.ignoreOffline", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Path to the media folder. Server stores audio, video and photo files in that folder. Sub-folders will be @@ -520,7 +520,7 @@ public final class Keys { */ public static final ConfigKey MEDIA_PATH = new ConfigKey<>( "media.path", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Optional parameter to specify network interface for web interface to bind to. By default server will bind to all @@ -528,7 +528,7 @@ public final class Keys { */ public static final ConfigKey WEB_ADDRESS = new ConfigKey<>( "web.address", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Web interface TCP port number. By default Traccar uses port 8082. To avoid specifying port in the browser you @@ -536,7 +536,7 @@ public final class Keys { */ public static final ConfigKey WEB_PORT = new ConfigKey<>( "web.port", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based @@ -544,21 +544,21 @@ public final class Keys { */ public static final ConfigKey WEB_SANITIZE = new ConfigKey<>( "web.sanitize", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Path to the web app folder. */ public static final ConfigKey WEB_PATH = new ConfigKey<>( "web.path", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * WebSocket connection timeout in milliseconds. Default timeout is 10 minutes. */ public static final ConfigKey WEB_TIMEOUT = new ConfigKey<>( "web.timeout", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 60000L); /** @@ -566,14 +566,14 @@ public final class Keys { */ public static final ConfigKey WEB_SESSION_TIMEOUT = new ConfigKey<>( "web.sessionTimeout", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable database access console via '/console' URL. Use only for debugging. Never use in production. */ public static final ConfigKey WEB_CONSOLE = new ConfigKey<>( "web.console", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Server debug version of the web app. Not recommended to use for performance reasons. It is intended to be used @@ -581,21 +581,21 @@ public final class Keys { */ public static final ConfigKey WEB_DEBUG = new ConfigKey<>( "web.debug", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Cross-origin resource sharing origin header value. */ public static final ConfigKey WEB_ORIGIN = new ConfigKey<>( "web.origin", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Cache control header value. By default resources are cached for one hour. */ public static final ConfigKey WEB_CACHE_CONTROL = new ConfigKey<>( "web.cacheControl", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "max-age=3600,public"); /** @@ -604,21 +604,21 @@ public final class Keys { */ public static final ConfigKey FORWARD_URL = new ConfigKey<>( "forward.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Additional HTTP header, can be used for authorization. */ public static final ConfigKey FORWARD_HEADER = new ConfigKey<>( "forward.header", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean value to enable forwarding in JSON format. */ public static final ConfigKey FORWARD_JSON = new ConfigKey<>( "forward.json", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean value to enable URL parameters in json mode. For example, {uniqueId} for device identifier, @@ -626,7 +626,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_URL_VARIABLES = new ConfigKey<>( "forward.urlVariables", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial @@ -637,7 +637,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_ENABLE = new ConfigKey<>( "forward.retry.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retry first delay in milliseconds. @@ -645,7 +645,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_DELAY = new ConfigKey<>( "forward.retry.delay", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retry maximum retries. @@ -653,7 +653,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_COUNT = new ConfigKey<>( "forward.retry.count", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retry pending positions limit. @@ -661,14 +661,14 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_LIMIT = new ConfigKey<>( "forward.retry.limit", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Events forwarding URL. */ public static final ConfigKey EVENT_FORWARD_URL = new ConfigKey<>( "event.forward.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Events forwarding headers. Example value: @@ -677,7 +677,7 @@ public final class Keys { */ public static final ConfigKey EVENT_FORWARD_HEADERS = new ConfigKey<>( "event.forward.header", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable commands queuing when devices are offline. Commands are buffered in memory only, so restarting service @@ -685,14 +685,14 @@ public final class Keys { */ public static final ConfigKey COMMANDS_QUEUEING = new ConfigKey<>( "commands.queueing", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Root folder for all template files. */ public static final ConfigKey TEMPLATES_ROOT = new ConfigKey<>( "templates.root", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "templates"); /** @@ -700,14 +700,14 @@ public final class Keys { */ public static final ConfigKey SMS_HTTP_URL = new ConfigKey<>( "sms.http.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API authorization header name. Default value is 'Authorization'. */ public static final ConfigKey SMS_HTTP_AUTHORIZATION_HEADER = new ConfigKey<>( "sms.http.authorizationHeader", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "Authorization"); /** @@ -715,21 +715,21 @@ public final class Keys { */ public static final ConfigKey SMS_HTTP_AUTHORIZATION = new ConfigKey<>( "sms.http.authorization", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API basic authentication user. */ public static final ConfigKey SMS_HTTP_USER = new ConfigKey<>( "sms.http.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API basic authentication password. */ public static final ConfigKey SMS_HTTP_PASSWORD = new ConfigKey<>( "sms.http.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API body template. Placeholders {phone} and {message} can be used in the template. @@ -737,21 +737,21 @@ public final class Keys { */ public static final ConfigKey SMS_HTTP_TEMPLATE = new ConfigKey<>( "sms.http.template", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * AWS Access Key with SNS permission. */ public static final ConfigKey SMS_AWS_ACCESS = new ConfigKey<>( "sms.aws.access", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * AWS Secret Access Key with SNS permission. */ public static final ConfigKey SMS_AWS_SECRET = new ConfigKey<>( "sms.aws.secret", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * AWS Region for SNS service. @@ -759,7 +759,7 @@ public final class Keys { */ public static final ConfigKey SMS_AWS_REGION = new ConfigKey<>( "sms.aws.region", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enabled notification options. Comma-separated string is expected. @@ -767,56 +767,56 @@ public final class Keys { */ public static final ConfigKey NOTIFICATOR_TYPES = new ConfigKey<>( "notificator.types", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Traccar notification API key. */ public static final ConfigKey NOTIFICATOR_TRACCAR_KEY = new ConfigKey<>( "notificator.traccar.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Firebase server API key for push notifications. */ public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new ConfigKey<>( "notificator.firebase.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Pushover notification user name. */ public static final ConfigKey NOTIFICATOR_PUSHOVER_USER = new ConfigKey<>( "notificator.pushover.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Pushover notification user token. */ public static final ConfigKey NOTIFICATOR_PUSHOVER_TOKEN = new ConfigKey<>( "notificator.pushover.token", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Telegram notification API key. */ public static final ConfigKey NOTIFICATOR_TELEGRAM_KEY = new ConfigKey<>( "notificator.telegram.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Telegram notification chat id to post messages to. */ public static final ConfigKey NOTIFICATOR_TELEGRAM_CHAT_ID = new ConfigKey<>( "notificator.telegram.chatId", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Telegram notification send location message. */ public static final ConfigKey NOTIFICATOR_TELEGRAM_SEND_LOCATION = new ConfigKey<>( "notificator.telegram.sendLocation", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Maximum time period for reports in seconds. Can be useful to prevent users to request unreasonably long reports. @@ -824,14 +824,14 @@ public final class Keys { */ public static final ConfigKey REPORT_PERIOD_LIMIT = new ConfigKey<>( "report.periodLimit", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Trips less than minimal duration and minimal distance are ignored. 300 seconds and 500 meters are default. */ public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DISTANCE = new ConfigKey<>( "report.trip.minimalTripDistance", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 500L); /** @@ -839,7 +839,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DURATION = new ConfigKey<>( "report.trip.minimalTripDuration", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 300L); /** @@ -847,7 +847,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_PARKING_DURATION = new ConfigKey<>( "report.trip.minimalParkingDuration", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 300L); /** @@ -855,7 +855,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_NO_DATA_DURATION = new ConfigKey<>( "report.trip.minimalNoDataDuration", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 3600L); /** @@ -863,21 +863,21 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_USE_IGNITION = new ConfigKey<>( "report.trip.useIgnition", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable or disable position filtering. */ public static final ConfigKey FILTER_ENABLE = new ConfigKey<>( "filter.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter invalid (valid field is set to false) positions. */ public static final ConfigKey FILTER_INVALID = new ConfigKey<>( "filter.invalid", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter zero coordinates. Zero latitude and longitude are theoretically valid values, but it practice it usually @@ -885,14 +885,14 @@ public final class Keys { */ public static final ConfigKey FILTER_ZERO = new ConfigKey<>( "filter.zero", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter duplicate records (duplicates are detected by time value). */ public static final ConfigKey FILTER_DUPLICATE = new ConfigKey<>( "filter.duplicate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter records with fix time in future. The values is specified in seconds. Records that have fix time more than @@ -900,28 +900,28 @@ public final class Keys { */ public static final ConfigKey FILTER_FUTURE = new ConfigKey<>( "filter.future", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter positions with accuracy less than specified value in meters. */ public static final ConfigKey FILTER_ACCURACY = new ConfigKey<>( "filter.accuracy", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter cell and wifi locations that are coming from geolocation provider. */ public static final ConfigKey FILTER_APPROXIMATE = new ConfigKey<>( "filter.approximate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter positions with exactly zero speed values. */ public static final ConfigKey FILTER_STATIC = new ConfigKey<>( "filter.static", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter records by distance. The values is specified in meters. If the new position is less far than this value @@ -929,7 +929,7 @@ public final class Keys { */ public static final ConfigKey FILTER_DISTANCE = new ConfigKey<>( "filter.distance", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if Position @@ -940,14 +940,14 @@ public final class Keys { */ public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey<>( "filter.maxSpeed", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter position if time from previous position is less than specified value in seconds. */ public static final ConfigKey FILTER_MIN_PERIOD = new ConfigKey<>( "filter.minPeriod", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, @@ -959,7 +959,7 @@ public final class Keys { */ public static final ConfigKey FILTER_RELATIVE = new ConfigKey<>( "filter.relative", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Time limit for the filtering in seconds. If the time difference between the last position was received by server @@ -967,7 +967,7 @@ public final class Keys { */ public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey<>( "filter.skipLimit", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable attributes skipping. Attribute skipping can be enabled in the config or device attributes. @@ -975,14 +975,14 @@ public final class Keys { */ public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey<>( "filter.skipAttributes.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Override device time. Possible values are 'deviceTime' and 'serverTime' */ public static final ConfigKey TIME_OVERRIDE = new ConfigKey<>( "time.override", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * List of protocols for overriding time. If not specified override is applied globally. List consist of protocol @@ -990,7 +990,7 @@ public final class Keys { */ public static final ConfigKey TIME_PROTOCOLS = new ConfigKey<>( "time.protocols", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Replaces coordinates with last known if change is less than a 'coordinates.minError' meters @@ -999,14 +999,14 @@ public final class Keys { */ public static final ConfigKey COORDINATES_FILTER = new ConfigKey<>( "coordinates.filter", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Distance in meters. Distances below this value gets handled like explained in 'coordinates.filter'. */ public static final ConfigKey COORDINATES_MIN_ERROR = new ConfigKey<>( "coordinates.minError", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Distance in meters. Distances above this value gets handled like explained in 'coordinates.filter', but only if @@ -1014,14 +1014,14 @@ public final class Keys { */ public static final ConfigKey COORDINATES_MAX_ERROR = new ConfigKey<>( "coordinates.maxError", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable to save device IP addresses information. Disabled by default. */ public static final ConfigKey PROCESSING_REMOTE_ADDRESS_ENABLE = new ConfigKey<>( "processing.remoteAddress.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable copying of missing attributes from last position to the current one. Might be useful if device doesn't @@ -1029,21 +1029,21 @@ public final class Keys { */ public static final ConfigKey PROCESSING_COPY_ATTRIBUTES_ENABLE = new ConfigKey<>( "processing.copyAttributes.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable computed attributes processing. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new ConfigKey<>( "processing.computedAttributes.deviceAttributes", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable or disable reverse geocoder. */ public static final ConfigKey GEOCODER_ENABLE = new ConfigKey<>( "geocoder.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Reverse geocoder type. Check reverse geocoding documentation for more info. By default (if the value is not @@ -1051,63 +1051,63 @@ public final class Keys { */ public static final ConfigKey GEOCODER_TYPE = new ConfigKey<>( "geocoder.type", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Geocoder server URL. Applicable only to Nominatim and Gisgraphy providers. */ public static final ConfigKey GEOCODER_URL = new ConfigKey<>( "geocoder.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * App id for use with Here provider. */ public static final ConfigKey GEOCODER_ID = new ConfigKey<>( "geocoder.id", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider API key. Most providers require API keys. */ public static final ConfigKey GEOCODER_KEY = new ConfigKey<>( "geocoder.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Language parameter for providers that support localization (e.g. Google and Nominatim). */ public static final ConfigKey GEOCODER_LANGUAGE = new ConfigKey<>( "geocoder.language", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Address format string. Default value is %h %r, %t, %s, %c. See AddressFormat for more info. */ public static final ConfigKey GEOCODER_FORMAT = new ConfigKey<>( "geocoder.format", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Cache size for geocoding results. */ public static final ConfigKey GEOCODER_CACHE_SIZE = new ConfigKey<>( "geocoder.cacheSize", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Disable automatic reverse geocoding requests for all positions. */ public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new ConfigKey<>( "geocoder.ignorePositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to apply reverse geocoding to invalid positions. */ public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new ConfigKey<>( "geocoder.processInvalidPositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Optional parameter to specify minimum distance for new reverse geocoding request. If distance is less than @@ -1115,14 +1115,14 @@ public final class Keys { */ public static final ConfigKey GEOCODER_REUSE_DISTANCE = new ConfigKey<>( "geocoder.reuseDistance", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Perform geocoding when preparing reports and sending notifications. */ public static final ConfigKey GEOCODER_ON_REQUEST = new ConfigKey<>( "geocoder.onRequest", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable LBS location resolution. Some devices send cell towers information and WiFi point when GPS @@ -1131,7 +1131,7 @@ public final class Keys { */ public static final ConfigKey GEOLOCATION_ENABLE = new ConfigKey<>( "geolocation.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider to use for LBS location. Available options: google, mozilla and opencellid. By default opencellid is @@ -1140,63 +1140,63 @@ public final class Keys { */ public static final ConfigKey GEOLOCATION_TYPE = new ConfigKey<>( "geolocation.type", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Geolocation provider API URL address. Not required for most providers. */ public static final ConfigKey GEOLOCATION_URL = new ConfigKey<>( "geolocation.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider API key. OpenCellID service requires API key. */ public static final ConfigKey GEOLOCATION_KEY = new ConfigKey<>( "geolocation.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to apply geolocation to invalid positions. */ public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( "geolocation.processInvalidPositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default MCC value to use if device doesn't report MCC. */ public static final ConfigKey GEOLOCATION_MCC = new ConfigKey<>( "geolocation.mcc", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default MNC value to use if device doesn't report MNC. */ public static final ConfigKey GEOLOCATION_MNC = new ConfigKey<>( "geolocation.mnc", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable speed limit API to get speed limit values depending on location. Default value is false. */ public static final ConfigKey SPEED_LIMIT_ENABLE = new ConfigKey<>( "speedLimit.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider to use for speed limit. Available options: overpass. By default overpass is used. */ public static final ConfigKey SPEED_LIMIT_TYPE = new ConfigKey<>( "speedLimit.type", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Speed limit provider API URL address. */ public static final ConfigKey SPEED_LIMIT_URL = new ConfigKey<>( "speedLimit.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Override latitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can be @@ -1204,7 +1204,7 @@ public final class Keys { */ public static final ConfigKey LOCATION_LATITUDE_HEMISPHERE = new ConfigKey<>( "location.latitudeHemisphere", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Override longitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can @@ -1212,7 +1212,7 @@ public final class Keys { */ public static final ConfigKey LOCATION_LONGITUDE_HEMISPHERE = new ConfigKey<>( "location.longitudeHemisphere", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Jetty Request Log Path. @@ -1222,21 +1222,21 @@ public final class Keys { */ public static final ConfigKey WEB_REQUEST_LOG_PATH = new ConfigKey<>( "web.requestLog.path", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Set the number of days before rotated request log files are deleted. */ public static final ConfigKey WEB_REQUEST_LOG_RETAIN_DAYS = new ConfigKey<>( "web.requestLog.retainDays", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Disable systemd health checks. */ public static final ConfigKey WEB_DISABLE_HEALTH_CHECK = new ConfigKey<>( "web.disableHealthCheck", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Sets SameSite cookie attribute value. @@ -1244,14 +1244,14 @@ public final class Keys { */ public static final ConfigKey WEB_SAME_SITE_COOKIE = new ConfigKey<>( "web.sameSiteCookie", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enables persisting Jetty session to the database */ public static final ConfigKey WEB_PERSIST_SESSION = new ConfigKey<>( "web.persistSession", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Public URL for the web app. Used for notification and report link. @@ -1260,28 +1260,28 @@ public final class Keys { */ public static final ConfigKey WEB_URL = new ConfigKey<>( "web.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Output logging to the standard terminal output instead of a log file. */ public static final ConfigKey LOGGER_CONSOLE = new ConfigKey<>( "logger.console", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Log executed SQL queries. */ public static final ConfigKey LOGGER_QUERIES = new ConfigKey<>( "logger.queries", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Log file name. For rotating logs, a date is added at the end of the file name for non-current logs. */ public static final ConfigKey LOGGER_FILE = new ConfigKey<>( "logger.file", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Logging level. Default value is 'info'. @@ -1289,14 +1289,14 @@ public final class Keys { */ public static final ConfigKey LOGGER_LEVEL = new ConfigKey<>( "logger.level", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Print full exception traces. Useful for debugging. By default shortened traces are logged. */ public static final ConfigKey LOGGER_FULL_STACK_TRACES = new ConfigKey<>( "logger.fullStackTraces", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Create a new log file daily. Helps with log management. For example, downloading and cleaning logs. Enabled by @@ -1304,14 +1304,14 @@ public final class Keys { */ public static final ConfigKey LOGGER_ROTATE = new ConfigKey<>( "logger.rotate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * A list of position attributes to log. */ public static final ConfigKey LOGGER_ATTRIBUTES = new ConfigKey<>( "logger.attributes", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "time,position,speed,course,accuracy,result"); /** @@ -1319,13 +1319,13 @@ public final class Keys { */ public static final ConfigKey BROADCAST_ADDRESS = new ConfigKey<>( "broadcast.address", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Multicast port for broadcasting synchronization events. */ public static final ConfigKey BROADCAST_PORT = new ConfigKey<>( "broadcast.port", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); } -- cgit v1.2.3 From c248ed30047a0525bf792730a0fbd4de0c89ad8e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:00:52 -0700 Subject: Refactor attribute lookup --- src/main/java/org/traccar/BaseProtocolDecoder.java | 14 +- src/main/java/org/traccar/config/ConfigKey.java | 73 +- src/main/java/org/traccar/config/ConfigSuffix.java | 81 ++- src/main/java/org/traccar/config/Keys.java | 779 ++++++++++++--------- .../java/org/traccar/database/DeviceManager.java | 57 -- .../java/org/traccar/database/IdentityManager.java | 11 - .../java/org/traccar/handler/FilterHandler.java | 48 +- .../org/traccar/handler/HemisphereHandler.java | 2 +- .../handler/events/FuelDropEventHandler.java | 25 +- .../handler/events/OverspeedEventHandler.java | 13 +- .../org/traccar/helper/model/AttributeUtil.java | 72 ++ src/main/java/org/traccar/model/CellTower.java | 2 +- .../traccar/protocol/StarLinkProtocolDecoder.java | 14 +- .../traccar/protocol/SuntechProtocolDecoder.java | 25 +- .../org/traccar/session/ConnectionManager.java | 5 +- .../org/traccar/session/cache/CacheManager.java | 4 + src/test/java/org/traccar/BaseTest.java | 15 +- .../org/traccar/handler/FilterHandlerTest.java | 21 +- .../handler/events/OverspeedEventHandlerTest.java | 2 +- 19 files changed, 748 insertions(+), 515 deletions(-) create mode 100644 src/main/java/org/traccar/helper/model/AttributeUtil.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index cbcb429b3..076b52e96 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -23,11 +23,13 @@ import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -46,6 +48,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final Protocol protocol; private IdentityManager identityManager; + private CacheManager cacheManager; private ConnectionManager connectionManager; private StatisticsManager statisticsManager; private MediaManager mediaManager; @@ -64,6 +67,15 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.identityManager = identityManager; } + public CacheManager getCacheManager() { + return cacheManager; + } + + @Inject + public void setCacheManager(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + @Inject public void setConnectionManager(ConnectionManager connectionManager) { this.connectionManager = connectionManager; @@ -125,7 +137,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { protected TimeZone getTimeZone(long deviceId, String defaultTimeZone) { TimeZone result = TimeZone.getTimeZone(defaultTimeZone); - String timeZoneName = identityManager.lookupAttributeString(deviceId, "decoder.timezone", null, false, true); + String timeZoneName = AttributeUtil.lookup(cacheManager, Keys.DECODER_TIMEZONE, deviceId); if (timeZoneName != null) { result = TimeZone.getTimeZone(timeZoneName); } diff --git a/src/main/java/org/traccar/config/ConfigKey.java b/src/main/java/org/traccar/config/ConfigKey.java index c046a46a5..b8151392c 100644 --- a/src/main/java/org/traccar/config/ConfigKey.java +++ b/src/main/java/org/traccar/config/ConfigKey.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. @@ -15,30 +15,34 @@ */ package org.traccar.config; +import java.util.HashSet; import java.util.List; +import java.util.Set; -public class ConfigKey { +public abstract class ConfigKey { private final String key; - private final List types; + private final Set types = new HashSet<>(); + private final Class valueClass; private final T defaultValue; - ConfigKey(String key, List types) { - this(key, types, null); - } - - ConfigKey(String key, List types, T defaultValue) { + ConfigKey(String key, List types, Class valueClass, T defaultValue) { this.key = key; - this.types = types; + this.types.addAll(types); + this.valueClass = valueClass; this.defaultValue = defaultValue; } - String getKey() { + public String getKey() { return key; } - public List getTypes() { - return types; + public boolean hasType(KeyType type) { + return types.contains(type); + } + + public Class getValueClass() { + return valueClass; } public T getDefaultValue() { @@ -46,3 +50,48 @@ public class ConfigKey { } } + +class StringConfigKey extends ConfigKey { + StringConfigKey(String key, List types) { + super(key, types, String.class, null); + } + StringConfigKey(String key, List types, String defaultValue) { + super(key, types, String.class, defaultValue); + } +} + +class BooleanConfigKey extends ConfigKey { + BooleanConfigKey(String key, List types) { + super(key, types, Boolean.class, null); + } + BooleanConfigKey(String key, List types, Boolean defaultValue) { + super(key, types, Boolean.class, defaultValue); + } +} + +class IntegerConfigKey extends ConfigKey { + IntegerConfigKey(String key, List types) { + super(key, types, Integer.class, null); + } + IntegerConfigKey(String key, List types, Integer defaultValue) { + super(key, types, Integer.class, defaultValue); + } +} + +class LongConfigKey extends ConfigKey { + LongConfigKey(String key, List types) { + super(key, types, Long.class, null); + } + LongConfigKey(String key, List types, Long defaultValue) { + super(key, types, Long.class, defaultValue); + } +} + +class DoubleConfigKey extends ConfigKey { + DoubleConfigKey(String key, List types) { + super(key, types, Double.class, null); + } + DoubleConfigKey(String key, List types, Double defaultValue) { + super(key, types, Double.class, defaultValue); + } +} diff --git a/src/main/java/org/traccar/config/ConfigSuffix.java b/src/main/java/org/traccar/config/ConfigSuffix.java index ede4c107d..aac3219c6 100644 --- a/src/main/java/org/traccar/config/ConfigSuffix.java +++ b/src/main/java/org/traccar/config/ConfigSuffix.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. @@ -17,15 +17,11 @@ package org.traccar.config; import java.util.List; -public class ConfigSuffix { +public abstract class ConfigSuffix { - private final String keySuffix; - private final List types; - private final T defaultValue; - - ConfigSuffix(String keySuffix, List types) { - this(keySuffix, types, null); - } + protected final String keySuffix; + protected final List types; + protected final T defaultValue; ConfigSuffix(String keySuffix, List types, T defaultValue) { this.keySuffix = keySuffix; @@ -33,8 +29,71 @@ public class ConfigSuffix { this.defaultValue = defaultValue; } - public ConfigKey withPrefix(String prefix) { - return new ConfigKey<>(prefix + keySuffix, types, defaultValue); + public abstract ConfigKey withPrefix(String prefix); + +} + +class StringConfigSuffix extends ConfigSuffix { + StringConfigSuffix(String key, List types) { + super(key, types, null); + } + StringConfigSuffix(String key, List types, String defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new StringConfigKey(prefix + keySuffix, types, defaultValue); + } +} + +class BooleanConfigSuffix extends ConfigSuffix { + BooleanConfigSuffix(String key, List types) { + super(key, types, null); + } + BooleanConfigSuffix(String key, List types, Boolean defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new BooleanConfigKey(prefix + keySuffix, types, defaultValue); + } +} + +class IntegerConfigSuffix extends ConfigSuffix { + IntegerConfigSuffix(String key, List types) { + super(key, types, null); + } + IntegerConfigSuffix(String key, List types, Integer defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new IntegerConfigKey(prefix + keySuffix, types, defaultValue); } +} +class LongConfigSuffix extends ConfigSuffix { + LongConfigSuffix(String key, List types) { + super(key, types, null); + } + LongConfigSuffix(String key, List types, Long defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new LongConfigKey(prefix + keySuffix, types, defaultValue); + } +} + +class DoubleConfigSuffix extends ConfigSuffix { + DoubleConfigSuffix(String key, List types) { + super(key, types, null); + } + DoubleConfigSuffix(String key, List types, Double defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new DoubleConfigKey(prefix + keySuffix, types, defaultValue); + } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 292202de0..465751d38 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -15,7 +15,7 @@ */ package org.traccar.config; -import java.util.Collections; +import java.util.List; public final class Keys { @@ -25,39 +25,39 @@ public final class Keys { /** * Network interface for a the protocol. If not specified, server will bind all interfaces. */ - public static final ConfigSuffix PROTOCOL_ADDRESS = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_ADDRESS = new StringConfigSuffix( ".address", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Port number for the protocol. Most protocols use TCP on the transport layer. Some protocols use UDP. Some * support both TCP and UDP. */ - public static final ConfigSuffix PROTOCOL_PORT = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_PORT = new IntegerConfigSuffix( ".port", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * List of devices for polling protocols. List should contain unique ids separated by commas. Used only for polling * protocols. */ - public static final ConfigSuffix PROTOCOL_DEVICES = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DEVICES = new StringConfigSuffix( ".devices", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Polling interval in seconds. Used only for polling protocols. */ - public static final ConfigSuffix PROTOCOL_INTERVAL = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_INTERVAL = new LongConfigSuffix( ".interval", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable SSL support for the protocol. Not all protocols support this. */ - public static final ConfigSuffix PROTOCOL_SSL = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_SSL = new BooleanConfigSuffix( ".ssl", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Connection timeout value in seconds. Because sometimes there is no way to detect lost TCP connection old @@ -65,568 +65,640 @@ public final class Keys { * problems with establishing new connections when number of devices is high or devices data connections are * unstable. */ - public static final ConfigSuffix PROTOCOL_TIMEOUT = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_TIMEOUT = new IntegerConfigSuffix( ".timeout", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Device password. Commonly used in some protocol for sending commands. */ - public static final ConfigSuffix PROTOCOL_DEVICE_PASSWORD = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DEVICE_PASSWORD = new StringConfigSuffix( ".devicePassword", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default protocol mask to use. Currently used only by Skypatrol protocol. */ - public static final ConfigSuffix PROTOCOL_MASK = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_MASK = new IntegerConfigSuffix( ".mask", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Custom message length. Currently used only by H2 protocol for specifying binary message length. */ - public static final ConfigSuffix PROTOCOL_MESSAGE_LENGTH = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_MESSAGE_LENGTH = new IntegerConfigSuffix( ".messageLength", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable extended functionality for the protocol. The reason it's disabled by default is that not all devices * support it. */ - public static final ConfigSuffix PROTOCOL_EXTENDED = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_EXTENDED = new BooleanConfigSuffix( ".extended", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Decode string as UTF8 instead of ASCII. Only applicable for some protocols. */ - public static final ConfigSuffix PROTOCOL_UTF8 = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_UTF8 = new BooleanConfigSuffix( ".utf8", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable CAN decoding for the protocol. Similar to 'extended' configuration, it's not supported for some devices. */ - public static final ConfigSuffix PROTOCOL_CAN = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_CAN = new BooleanConfigSuffix( ".can", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Indicates whether server acknowledgement is required. Only applicable for some protocols. */ - public static final ConfigSuffix PROTOCOL_ACK = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_ACK = new BooleanConfigSuffix( ".ack", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Ignore device reported fix time. Useful in case some devices report invalid time. Currently only available for * GL200 protocol. */ - public static final ConfigSuffix PROTOCOL_IGNORE_FIX_TIME = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_IGNORE_FIX_TIME = new BooleanConfigSuffix( ".ignoreFixTime", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Decode additional TK103 attributes. Not supported for some devices. */ - public static final ConfigSuffix PROTOCOL_DECODE_LOW = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DECODE_LOW = new BooleanConfigSuffix( ".decodeLow", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Use long date format for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_LONG_DATE = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_LONG_DATE = new BooleanConfigSuffix( ".longDate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Use decimal fuel value format for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_DECIMAL_FUEL = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DECIMAL_FUEL = new BooleanConfigSuffix( ".decimalFuel", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Indicates additional custom attributes for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_CUSTOM = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_CUSTOM = new BooleanConfigSuffix( ".custom", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Custom format string for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_FORM = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_FORM = new StringConfigSuffix( ".form", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Protocol configuration. Required for some devices for decoding incoming data. */ - public static final ConfigSuffix PROTOCOL_CONFIG = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_CONFIG = new StringConfigSuffix( ".config", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Alarm mapping for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_ALARM_MAP = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_ALARM_MAP = new StringConfigSuffix( ".alarmMap", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Indicates whether TAIP protocol should have prefixes for messages. */ - public static final ConfigSuffix PROTOCOL_PREFIX = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_PREFIX = new BooleanConfigSuffix( ".prefix", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Some devices require server address confirmation. Use this parameter to configure correct public address. */ - public static final ConfigSuffix PROTOCOL_SERVER = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_SERVER = new StringConfigSuffix( ".server", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); + + /** + * Protocol type for Suntech. + */ + public static final ConfigKey PROTOCOL_TYPE = new IntegerConfigKey( + "suntech.protocolType", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Suntech HBM configuration value. + */ + public static final ConfigKey PROTOCOL_HBM = new BooleanConfigKey( + "suntech.hbm", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Format includes ADC value. + */ + public static final ConfigSuffix PROTOCOL_INCLUDE_ADC = new BooleanConfigSuffix( + ".includeAdc", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Format includes RPM value. + */ + public static final ConfigSuffix PROTOCOL_INCLUDE_RPM = new BooleanConfigSuffix( + ".includeRpm", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Format includes temperature values. + */ + public static final ConfigSuffix PROTOCOL_INCLUDE_TEMPERATURE = new BooleanConfigSuffix( + ".includeTemp", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Protocol format. Used by protocols that have configurable message format. + */ + public static final ConfigSuffix PROTOCOL_FORMAT = new StringConfigSuffix( + ".format", + List.of(KeyType.DEVICE)); + + /** + * Protocol date format. Used by protocols that have configurable date format. + */ + public static final ConfigSuffix PROTOCOL_DATE_FORMAT = new StringConfigSuffix( + ".dateFormat", + List.of(KeyType.DEVICE)); + + /** + * Device time zone. Most devices report UTC time, but in some cases devices report local time, so this parameter + * needs to be configured for the server to be able to decode the time correctly. + */ + public static final ConfigKey DECODER_TIMEZONE = new StringConfigKey( + "decoder.timezone", + List.of(KeyType.CONFIG, KeyType.DEVICE)); /** * ORBCOMM API access id. */ - public static final ConfigKey ORBCOMM_ACCESS_ID = new ConfigKey<>( + public static final ConfigKey ORBCOMM_ACCESS_ID = new StringConfigKey( "orbcomm.accessId", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * ORBCOMM API password. */ - public static final ConfigKey ORBCOMM_PASSWORD = new ConfigKey<>( + public static final ConfigKey ORBCOMM_PASSWORD = new StringConfigKey( "orbcomm.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ - public static final ConfigKey SERVER_TIMEOUT = new ConfigKey<>( + public static final ConfigKey SERVER_TIMEOUT = new IntegerConfigKey( "server.timeout", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Address for uploading aggregated anonymous usage statistics. Uploaded information is the same you can see on the * statistics screen in the web app. It does not include any sensitive (e.g. locations). */ - public static final ConfigKey SERVER_STATISTICS = new ConfigKey<>( + public static final ConfigKey SERVER_STATISTICS = new StringConfigKey( "server.statistics", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); + + /** + * Fuel drop threshold value. When fuel level drops from one position to another for more the value, an event is + * generated. + */ + public static final ConfigKey EVENT_FUEL_DROP_THRESHOLD = new DoubleConfigKey( + "fuelDropThreshold", + List.of(KeyType.SERVER, KeyType.DEVICE)); + + /** + * Speed limit value in knots. + */ + public static final ConfigKey EVENT_OVERSPEED_LIMIT = new DoubleConfigKey( + "speedLimit", + List.of(KeyType.SERVER, KeyType.DEVICE)); /** * If true, the event is generated once at the beginning of overspeeding period. */ - public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new ConfigKey<>( + public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new BooleanConfigKey( "event.overspeed.notRepeat", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Minimal over speed duration to trigger the event. Value in seconds. */ - public static final ConfigKey EVENT_OVERSPEED_MINIMAL_DURATION = new ConfigKey<>( + public static final ConfigKey EVENT_OVERSPEED_MINIMAL_DURATION = new LongConfigKey( "event.overspeed.minimalDuration", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Relevant only for geofence speed limits. Use the lowest speed limit from all geofences. */ - public static final ConfigKey EVENT_OVERSPEED_PREFER_LOWEST = new ConfigKey<>( + public static final ConfigKey EVENT_OVERSPEED_PREFER_LOWEST = new BooleanConfigKey( "event.overspeed.preferLowest", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Driver behavior acceleration threshold. Value is in meter per second squared. */ - public static final ConfigKey EVENT_BEHAVIOR_ACCELERATION_THRESHOLD = new ConfigKey<>( + public static final ConfigKey EVENT_BEHAVIOR_ACCELERATION_THRESHOLD = new DoubleConfigKey( "event.behavior.accelerationThreshold", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Driver behavior braking threshold. Value is in meter per second squared. */ - public static final ConfigKey EVENT_BEHAVIOR_BRAKING_THRESHOLD = new ConfigKey<>( + public static final ConfigKey EVENT_BEHAVIOR_BRAKING_THRESHOLD = new DoubleConfigKey( "event.behavior.brakingThreshold", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Do not generate alert event if same alert was present in last known location. */ - public static final ConfigKey EVENT_IGNORE_DUPLICATE_ALERTS = new ConfigKey<>( + public static final ConfigKey EVENT_IGNORE_DUPLICATE_ALERTS = new BooleanConfigKey( "event.ignoreDuplicateAlerts", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If set to true, invalid positions will be considered for motion logic. */ - public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( + public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "event.motion.processInvalidPositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If the speed is above specified value, the object is considered to be in motion. Default value is 0.01 knots. */ - public static final ConfigKey EVENT_MOTION_SPEED_THRESHOLD = new ConfigKey<>( + public static final ConfigKey EVENT_MOTION_SPEED_THRESHOLD = new DoubleConfigKey( "event.motion.speedThreshold", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 0.01); /** * Global polyline geofence distance. Within that distance from the polyline, point is considered within the * geofence. Each individual geofence can also has 'polylineDistance' attribute which will take precedence. */ - public static final ConfigKey GEOFENCE_POLYLINE_DISTANCE = new ConfigKey<>( + public static final ConfigKey GEOFENCE_POLYLINE_DISTANCE = new DoubleConfigKey( "geofence.polylineDistance", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 25.0); /** * Path to the database driver JAR file. Traccar includes drivers for MySQL, PostgreSQL and H2 databases. If you use * one of those, you don't need to specify this parameter. */ - public static final ConfigKey DATABASE_DRIVER_FILE = new ConfigKey<>( + public static final ConfigKey DATABASE_DRIVER_FILE = new StringConfigKey( "database.driverFile", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database driver Java class. For H2 use 'org.h2.Driver'. MySQL driver class name is 'com.mysql.jdbc.Driver'. */ - public static final ConfigKey DATABASE_DRIVER = new ConfigKey<>( + public static final ConfigKey DATABASE_DRIVER = new StringConfigKey( "database.driver", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database connection URL. By default Traccar uses H2 database. */ - public static final ConfigKey DATABASE_URL = new ConfigKey<>( + public static final ConfigKey DATABASE_URL = new StringConfigKey( "database.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database user name. Default administrator user for H2 database is 'sa'. */ - public static final ConfigKey DATABASE_USER = new ConfigKey<>( + public static final ConfigKey DATABASE_USER = new StringConfigKey( "database.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database user password. Default password for H2 admin (sa) user is empty. */ - public static final ConfigKey DATABASE_PASSWORD = new ConfigKey<>( + public static final ConfigKey DATABASE_PASSWORD = new StringConfigKey( "database.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Path to Liquibase master changelog file. */ - public static final ConfigKey DATABASE_CHANGELOG = new ConfigKey<>( + public static final ConfigKey DATABASE_CHANGELOG = new StringConfigKey( "database.changelog", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database connection pool size. Default value is defined by the HikariCP library. */ - public static final ConfigKey DATABASE_MAX_POOL_SIZE = new ConfigKey<>( + public static final ConfigKey DATABASE_MAX_POOL_SIZE = new IntegerConfigKey( "database.maxPoolSize", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SQL query to check connection status. Default value is 'SELECT 1'. For Oracle database you can use * 'SELECT 1 FROM DUAL'. */ - public static final ConfigKey DATABASE_CHECK_CONNECTION = new ConfigKey<>( + public static final ConfigKey DATABASE_CHECK_CONNECTION = new StringConfigKey( "database.checkConnection", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "SELECT 1"); /** * Store original HEX or string data as "raw" attribute in the corresponding position. */ - public static final ConfigKey DATABASE_SAVE_ORIGINAL = new ConfigKey<>( + public static final ConfigKey DATABASE_SAVE_ORIGINAL = new BooleanConfigKey( "database.saveOriginal", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * By default server syncs with the database if it encounters and unknown device. This flag allows to disable that * behavior to improve performance in some cases. */ - public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new ConfigKey<>( + public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new BooleanConfigKey( "database.ignoreUnknown", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Automatically register unknown devices in the database. */ - public static final ConfigKey DATABASE_REGISTER_UNKNOWN = new ConfigKey<>( + public static final ConfigKey DATABASE_REGISTER_UNKNOWN = new BooleanConfigKey( "database.registerUnknown", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default category for auto-registered devices. */ - public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY = new ConfigKey<>( + public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY = new StringConfigKey( "database.registerUnknown.defaultCategory", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * The group id assigned to auto-registered devices. */ - public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID = new ConfigKey<>( + public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID = new LongConfigKey( "database.registerUnknown.defaultGroupId", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Minimum device refresh timeout in seconds. Default timeout is 5 minutes. */ - public static final ConfigKey DATABASE_REFRESH_DELAY = new ConfigKey<>( + public static final ConfigKey DATABASE_REFRESH_DELAY = new LongConfigKey( "database.refreshDelay", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 300L); /** * Store empty messages as positions. For example, heartbeats. */ - public static final ConfigKey DATABASE_SAVE_EMPTY = new ConfigKey<>( + public static final ConfigKey DATABASE_SAVE_EMPTY = new BooleanConfigKey( "database.saveEmpty", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Device limit for self registered users. Default value is -1, which indicates no limit. */ - public static final ConfigKey USERS_DEFAULT_DEVICE_LIMIT = new ConfigKey<>( + public static final ConfigKey USERS_DEFAULT_DEVICE_LIMIT = new IntegerConfigKey( "users.defaultDeviceLimit", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), -1); /** * Default user expiration for self registered users. Value is in days. By default no expiration is set. */ - public static final ConfigKey USERS_DEFAULT_EXPIRATION_DAYS = new ConfigKey<>( + public static final ConfigKey USERS_DEFAULT_EXPIRATION_DAYS = new IntegerConfigKey( "users.defaultExpirationDays", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP server URL. */ - public static final ConfigKey LDAP_URL = new ConfigKey<>( + public static final ConfigKey LDAP_URL = new StringConfigKey( "ldap.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP server login. */ - public static final ConfigKey LDAP_USER = new ConfigKey<>( + public static final ConfigKey LDAP_USER = new StringConfigKey( "ldap.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP server password. */ - public static final ConfigKey LDAP_PASSWORD = new ConfigKey<>( + public static final ConfigKey LDAP_PASSWORD = new StringConfigKey( "ldap.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Force LDAP authentication. */ - public static final ConfigKey LDAP_FORCE = new ConfigKey<>( + public static final ConfigKey LDAP_FORCE = new BooleanConfigKey( "ldap.force", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP user search base. */ - public static final ConfigKey LDAP_BASE = new ConfigKey<>( + public static final ConfigKey LDAP_BASE = new StringConfigKey( "ldap.base", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP attribute used as user id. Default value is 'uid'. */ - public static final ConfigKey LDAP_ID_ATTRIBUTE = new ConfigKey<>( + public static final ConfigKey LDAP_ID_ATTRIBUTE = new StringConfigKey( "ldap.idAttribute", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "uid"); /** * LDAP attribute used as user name. Default value is 'cn'. */ - public static final ConfigKey LDAP_NAME_ATTRIBUTE = new ConfigKey<>( + public static final ConfigKey LDAP_NAME_ATTRIBUTE = new StringConfigKey( "ldap.nameAttribute", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "cn"); /** * LDAP attribute used as user email. Default value is 'mail'. */ - public static final ConfigKey LDAP_MAIN_ATTRIBUTE = new ConfigKey<>( + public static final ConfigKey LDAP_MAIN_ATTRIBUTE = new StringConfigKey( "ldap.mailAttribute", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "mail"); /** * LDAP custom search filter. If not specified, '({idAttribute}=:login)' will be used as a filter. */ - public static final ConfigKey LDAP_SEARCH_FILTER = new ConfigKey<>( + public static final ConfigKey LDAP_SEARCH_FILTER = new StringConfigKey( "ldap.searchFilter", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP custom admin search filter. */ - public static final ConfigKey LDAP_ADMIN_FILTER = new ConfigKey<>( + public static final ConfigKey LDAP_ADMIN_FILTER = new StringConfigKey( "ldap.adminFilter", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP admin user group. Used if custom admin filter is not specified. */ - public static final ConfigKey LDAP_ADMIN_GROUP = new ConfigKey<>( + public static final ConfigKey LDAP_ADMIN_GROUP = new StringConfigKey( "ldap.adminGroup", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If no data is reported by a device for the given amount of time, status changes from online to unknown. Value is * in seconds. Default timeout is 10 minutes. */ - public static final ConfigKey STATUS_TIMEOUT = new ConfigKey<>( + public static final ConfigKey STATUS_TIMEOUT = new LongConfigKey( "status.timeout", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 600L); /** * Force additional state check when device status changes to 'offline' or 'unknown'. Default false. */ - public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new ConfigKey<>( + public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new BooleanConfigKey( "status.updateDeviceState", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * List of protocol names to ignore offline status. Can be useful to not trigger status change when devices are * configured to disconnect after reporting a batch of data. */ - public static final ConfigKey STATUS_IGNORE_OFFLINE = new ConfigKey<>( + public static final ConfigKey STATUS_IGNORE_OFFLINE = new StringConfigKey( "status.ignoreOffline", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Path to the media folder. Server stores audio, video and photo files in that folder. Sub-folders will be * automatically created for each device by unique id. */ - public static final ConfigKey MEDIA_PATH = new ConfigKey<>( + public static final ConfigKey MEDIA_PATH = new StringConfigKey( "media.path", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Optional parameter to specify network interface for web interface to bind to. By default server will bind to all * available interfaces. */ - public static final ConfigKey WEB_ADDRESS = new ConfigKey<>( + public static final ConfigKey WEB_ADDRESS = new StringConfigKey( "web.address", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Web interface TCP port number. By default Traccar uses port 8082. To avoid specifying port in the browser you * can set it to 80 (default HTTP port). */ - public static final ConfigKey WEB_PORT = new ConfigKey<>( + public static final ConfigKey WEB_PORT = new IntegerConfigKey( "web.port", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based * interface doesn't require this. */ - public static final ConfigKey WEB_SANITIZE = new ConfigKey<>( + public static final ConfigKey WEB_SANITIZE = new BooleanConfigKey( "web.sanitize", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Path to the web app folder. */ - public static final ConfigKey WEB_PATH = new ConfigKey<>( + public static final ConfigKey WEB_PATH = new StringConfigKey( "web.path", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * WebSocket connection timeout in milliseconds. Default timeout is 10 minutes. */ - public static final ConfigKey WEB_TIMEOUT = new ConfigKey<>( + public static final ConfigKey WEB_TIMEOUT = new LongConfigKey( "web.timeout", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 60000L); /** * Authentication sessions timeout in seconds. By default no timeout. */ - public static final ConfigKey WEB_SESSION_TIMEOUT = new ConfigKey<>( + public static final ConfigKey WEB_SESSION_TIMEOUT = new IntegerConfigKey( "web.sessionTimeout", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable database access console via '/console' URL. Use only for debugging. Never use in production. */ - public static final ConfigKey WEB_CONSOLE = new ConfigKey<>( + public static final ConfigKey WEB_CONSOLE = new BooleanConfigKey( "web.console", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Server debug version of the web app. Not recommended to use for performance reasons. It is intended to be used * for development and debugging purposes. */ - public static final ConfigKey WEB_DEBUG = new ConfigKey<>( + public static final ConfigKey WEB_DEBUG = new BooleanConfigKey( "web.debug", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Cross-origin resource sharing origin header value. */ - public static final ConfigKey WEB_ORIGIN = new ConfigKey<>( + public static final ConfigKey WEB_ORIGIN = new StringConfigKey( "web.origin", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Cache control header value. By default resources are cached for one hour. */ - public static final ConfigKey WEB_CACHE_CONTROL = new ConfigKey<>( + public static final ConfigKey WEB_CACHE_CONTROL = new StringConfigKey( "web.cacheControl", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "max-age=3600,public"); /** * URL to forward positions. Data is passed through URL parameters. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. */ - public static final ConfigKey FORWARD_URL = new ConfigKey<>( + public static final ConfigKey FORWARD_URL = new StringConfigKey( "forward.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Additional HTTP header, can be used for authorization. */ - public static final ConfigKey FORWARD_HEADER = new ConfigKey<>( + public static final ConfigKey FORWARD_HEADER = new StringConfigKey( "forward.header", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean value to enable forwarding in JSON format. */ - public static final ConfigKey FORWARD_JSON = new ConfigKey<>( + public static final ConfigKey FORWARD_JSON = new BooleanConfigKey( "forward.json", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean value to enable URL parameters in json mode. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. */ - public static final ConfigKey FORWARD_URL_VARIABLES = new ConfigKey<>( + public static final ConfigKey FORWARD_URL_VARIABLES = new BooleanConfigKey( "forward.urlVariables", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial @@ -635,301 +707,301 @@ public final class Keys { * If forwarding is retried for 'forward.retry.count', retrying is canceled and the position is dropped. Positions * pending to be delivered are limited to 'forward.retry.limit'. If this limit is reached, positions get discarded. */ - public static final ConfigKey FORWARD_RETRY_ENABLE = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_ENABLE = new BooleanConfigKey( "forward.retry.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retry first delay in milliseconds. * Can be set to anything greater than 0. Defaults to 100 milliseconds. */ - public static final ConfigKey FORWARD_RETRY_DELAY = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_DELAY = new IntegerConfigKey( "forward.retry.delay", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retry maximum retries. * Can be set to anything greater than 0. Defaults to 10 retries. */ - public static final ConfigKey FORWARD_RETRY_COUNT = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_COUNT = new IntegerConfigKey( "forward.retry.count", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retry pending positions limit. * Can be set to anything greater than 0. Defaults to 100 positions. */ - public static final ConfigKey FORWARD_RETRY_LIMIT = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_LIMIT = new IntegerConfigKey( "forward.retry.limit", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Events forwarding URL. */ - public static final ConfigKey EVENT_FORWARD_URL = new ConfigKey<>( + public static final ConfigKey EVENT_FORWARD_URL = new StringConfigKey( "event.forward.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Events forwarding headers. Example value: * FirstHeader: hello * SecondHeader: world */ - public static final ConfigKey EVENT_FORWARD_HEADERS = new ConfigKey<>( + public static final ConfigKey EVENT_FORWARD_HEADERS = new StringConfigKey( "event.forward.header", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable commands queuing when devices are offline. Commands are buffered in memory only, so restarting service * will clear the buffer. */ - public static final ConfigKey COMMANDS_QUEUEING = new ConfigKey<>( + public static final ConfigKey COMMANDS_QUEUEING = new BooleanConfigKey( "commands.queueing", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Root folder for all template files. */ - public static final ConfigKey TEMPLATES_ROOT = new ConfigKey<>( + public static final ConfigKey TEMPLATES_ROOT = new StringConfigKey( "templates.root", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "templates"); /** * SMS API service full URL. Enables SMS commands and notifications. */ - public static final ConfigKey SMS_HTTP_URL = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_URL = new StringConfigKey( "sms.http.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API authorization header name. Default value is 'Authorization'. */ - public static final ConfigKey SMS_HTTP_AUTHORIZATION_HEADER = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_AUTHORIZATION_HEADER = new StringConfigKey( "sms.http.authorizationHeader", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "Authorization"); /** * SMS API authorization header value. This value takes precedence over user and password. */ - public static final ConfigKey SMS_HTTP_AUTHORIZATION = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_AUTHORIZATION = new StringConfigKey( "sms.http.authorization", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API basic authentication user. */ - public static final ConfigKey SMS_HTTP_USER = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_USER = new StringConfigKey( "sms.http.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API basic authentication password. */ - public static final ConfigKey SMS_HTTP_PASSWORD = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_PASSWORD = new StringConfigKey( "sms.http.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API body template. Placeholders {phone} and {message} can be used in the template. * If value starts with '{' or '[', server automatically assumes JSON format. */ - public static final ConfigKey SMS_HTTP_TEMPLATE = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_TEMPLATE = new StringConfigKey( "sms.http.template", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * AWS Access Key with SNS permission. */ - public static final ConfigKey SMS_AWS_ACCESS = new ConfigKey<>( + public static final ConfigKey SMS_AWS_ACCESS = new StringConfigKey( "sms.aws.access", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * AWS Secret Access Key with SNS permission. */ - public static final ConfigKey SMS_AWS_SECRET = new ConfigKey<>( + public static final ConfigKey SMS_AWS_SECRET = new StringConfigKey( "sms.aws.secret", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * AWS Region for SNS service. * Make sure to use regions that are supported for messaging. */ - public static final ConfigKey SMS_AWS_REGION = new ConfigKey<>( + public static final ConfigKey SMS_AWS_REGION = new StringConfigKey( "sms.aws.region", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enabled notification options. Comma-separated string is expected. * Example: web,mail,sms */ - public static final ConfigKey NOTIFICATOR_TYPES = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TYPES = new StringConfigKey( "notificator.types", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Traccar notification API key. */ - public static final ConfigKey NOTIFICATOR_TRACCAR_KEY = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TRACCAR_KEY = new StringConfigKey( "notificator.traccar.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Firebase server API key for push notifications. */ - public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new StringConfigKey( "notificator.firebase.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Pushover notification user name. */ - public static final ConfigKey NOTIFICATOR_PUSHOVER_USER = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_PUSHOVER_USER = new StringConfigKey( "notificator.pushover.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Pushover notification user token. */ - public static final ConfigKey NOTIFICATOR_PUSHOVER_TOKEN = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_PUSHOVER_TOKEN = new StringConfigKey( "notificator.pushover.token", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Telegram notification API key. */ - public static final ConfigKey NOTIFICATOR_TELEGRAM_KEY = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TELEGRAM_KEY = new StringConfigKey( "notificator.telegram.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Telegram notification chat id to post messages to. */ - public static final ConfigKey NOTIFICATOR_TELEGRAM_CHAT_ID = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TELEGRAM_CHAT_ID = new StringConfigKey( "notificator.telegram.chatId", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Telegram notification send location message. */ - public static final ConfigKey NOTIFICATOR_TELEGRAM_SEND_LOCATION = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TELEGRAM_SEND_LOCATION = new BooleanConfigKey( "notificator.telegram.sendLocation", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Maximum time period for reports in seconds. Can be useful to prevent users to request unreasonably long reports. * By default there is no limit. */ - public static final ConfigKey REPORT_PERIOD_LIMIT = new ConfigKey<>( + public static final ConfigKey REPORT_PERIOD_LIMIT = new LongConfigKey( "report.periodLimit", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Trips less than minimal duration and minimal distance are ignored. 300 seconds and 500 meters are default. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DISTANCE = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DISTANCE = new LongConfigKey( "report.trip.minimalTripDistance", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 500L); /** * Trips less than minimal duration and minimal distance are ignored. 300 seconds and 500 meters are default. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DURATION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DURATION = new LongConfigKey( "report.trip.minimalTripDuration", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 300L); /** * Parking less than minimal duration does not cut trip. Default 300 seconds. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_PARKING_DURATION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_PARKING_DURATION = new LongConfigKey( "report.trip.minimalParkingDuration", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 300L); /** * Gaps of more than specified time are counted as stops. Default value is one hour. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_NO_DATA_DURATION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_NO_DATA_DURATION = new LongConfigKey( "report.trip.minimalNoDataDuration", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 3600L); /** * Flag to enable ignition use for trips calculation. */ - public static final ConfigKey REPORT_TRIP_USE_IGNITION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_USE_IGNITION = new BooleanConfigKey( "report.trip.useIgnition", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable or disable position filtering. */ - public static final ConfigKey FILTER_ENABLE = new ConfigKey<>( + public static final ConfigKey FILTER_ENABLE = new BooleanConfigKey( "filter.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter invalid (valid field is set to false) positions. */ - public static final ConfigKey FILTER_INVALID = new ConfigKey<>( + public static final ConfigKey FILTER_INVALID = new BooleanConfigKey( "filter.invalid", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter zero coordinates. Zero latitude and longitude are theoretically valid values, but it practice it usually * indicates invalid GPS data. */ - public static final ConfigKey FILTER_ZERO = new ConfigKey<>( + public static final ConfigKey FILTER_ZERO = new BooleanConfigKey( "filter.zero", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter duplicate records (duplicates are detected by time value). */ - public static final ConfigKey FILTER_DUPLICATE = new ConfigKey<>( + public static final ConfigKey FILTER_DUPLICATE = new BooleanConfigKey( "filter.duplicate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter records with fix time in future. The values is specified in seconds. Records that have fix time more than * specified number of seconds later than current server time would be filtered out. */ - public static final ConfigKey FILTER_FUTURE = new ConfigKey<>( + public static final ConfigKey FILTER_FUTURE = new LongConfigKey( "filter.future", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter positions with accuracy less than specified value in meters. */ - public static final ConfigKey FILTER_ACCURACY = new ConfigKey<>( + public static final ConfigKey FILTER_ACCURACY = new IntegerConfigKey( "filter.accuracy", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter cell and wifi locations that are coming from geolocation provider. */ - public static final ConfigKey FILTER_APPROXIMATE = new ConfigKey<>( + public static final ConfigKey FILTER_APPROXIMATE = new BooleanConfigKey( "filter.approximate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter positions with exactly zero speed values. */ - public static final ConfigKey FILTER_STATIC = new ConfigKey<>( + public static final ConfigKey FILTER_STATIC = new BooleanConfigKey( "filter.static", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter records by distance. The values is specified in meters. If the new position is less far than this value * from the last one it gets filtered out. */ - public static final ConfigKey FILTER_DISTANCE = new ConfigKey<>( + public static final ConfigKey FILTER_DISTANCE = new IntegerConfigKey( "filter.distance", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if Position @@ -938,16 +1010,16 @@ public final class Keys { * * Tip: Shouldn't be too low. Start testing with values at about 25000. */ - public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey<>( + public static final ConfigKey FILTER_MAX_SPEED = new IntegerConfigKey( "filter.maxSpeed", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter position if time from previous position is less than specified value in seconds. */ - public static final ConfigKey FILTER_MIN_PERIOD = new ConfigKey<>( + public static final ConfigKey FILTER_MIN_PERIOD = new IntegerConfigKey( "filter.minPeriod", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, @@ -957,262 +1029,271 @@ public final class Keys { * Filter checks for duplicates, distance, speed, or time period against the preceding Position's. * Important: setting to true can cause potential performance issues. */ - public static final ConfigKey FILTER_RELATIVE = new ConfigKey<>( + public static final ConfigKey FILTER_RELATIVE = new BooleanConfigKey( "filter.relative", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Time limit for the filtering in seconds. If the time difference between the last position was received by server * and a new position is received by server is more than this limit, the new position will not be filtered out. */ - public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey<>( + public static final ConfigKey FILTER_SKIP_LIMIT = new LongConfigKey( "filter.skipLimit", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable attributes skipping. Attribute skipping can be enabled in the config or device attributes. * If position contains any attribute mentioned in "filter.skipAttributes" config key, position is not filtered out. */ - public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey<>( + public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new BooleanConfigKey( "filter.skipAttributes.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); + + /** + * Attribute skipping can be enabled in the config or device attributes. + * If position contains any attribute mentioned in "filter.skipAttributes" config key, position is not filtered out. + */ + public static final ConfigKey FILTER_SKIP_ATTRIBUTES = new StringConfigKey( + "filter.skipAttributes", + List.of(KeyType.CONFIG, KeyType.DEVICE), + ""); /** * Override device time. Possible values are 'deviceTime' and 'serverTime' */ - public static final ConfigKey TIME_OVERRIDE = new ConfigKey<>( + public static final ConfigKey TIME_OVERRIDE = new StringConfigKey( "time.override", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * List of protocols for overriding time. If not specified override is applied globally. List consist of protocol * names that can be separated by comma or single space character. */ - public static final ConfigKey TIME_PROTOCOLS = new ConfigKey<>( + public static final ConfigKey TIME_PROTOCOLS = new StringConfigKey( "time.protocols", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Replaces coordinates with last known if change is less than a 'coordinates.minError' meters * or more than a 'coordinates.maxError' meters. Helps to avoid coordinates jumps during parking period * or jumps to zero coordinates. */ - public static final ConfigKey COORDINATES_FILTER = new ConfigKey<>( + public static final ConfigKey COORDINATES_FILTER = new BooleanConfigKey( "coordinates.filter", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Distance in meters. Distances below this value gets handled like explained in 'coordinates.filter'. */ - public static final ConfigKey COORDINATES_MIN_ERROR = new ConfigKey<>( + public static final ConfigKey COORDINATES_MIN_ERROR = new IntegerConfigKey( "coordinates.minError", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Distance in meters. Distances above this value gets handled like explained in 'coordinates.filter', but only if * Position is also marked as 'invalid'. */ - public static final ConfigKey COORDINATES_MAX_ERROR = new ConfigKey<>( + public static final ConfigKey COORDINATES_MAX_ERROR = new IntegerConfigKey( "coordinates.maxError", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable to save device IP addresses information. Disabled by default. */ - public static final ConfigKey PROCESSING_REMOTE_ADDRESS_ENABLE = new ConfigKey<>( + public static final ConfigKey PROCESSING_REMOTE_ADDRESS_ENABLE = new BooleanConfigKey( "processing.remoteAddress.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * 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. */ - public static final ConfigKey PROCESSING_COPY_ATTRIBUTES_ENABLE = new ConfigKey<>( + public static final ConfigKey PROCESSING_COPY_ATTRIBUTES_ENABLE = new BooleanConfigKey( "processing.copyAttributes.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable computed attributes processing. */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new ConfigKey<>( + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new BooleanConfigKey( "processing.computedAttributes.deviceAttributes", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable or disable reverse geocoder. */ - public static final ConfigKey GEOCODER_ENABLE = new ConfigKey<>( + public static final ConfigKey GEOCODER_ENABLE = new BooleanConfigKey( "geocoder.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Reverse geocoder type. Check reverse geocoding documentation for more info. By default (if the value is not * specified) server uses Google API. */ - public static final ConfigKey GEOCODER_TYPE = new ConfigKey<>( + public static final ConfigKey GEOCODER_TYPE = new StringConfigKey( "geocoder.type", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Geocoder server URL. Applicable only to Nominatim and Gisgraphy providers. */ - public static final ConfigKey GEOCODER_URL = new ConfigKey<>( + public static final ConfigKey GEOCODER_URL = new StringConfigKey( "geocoder.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * App id for use with Here provider. */ - public static final ConfigKey GEOCODER_ID = new ConfigKey<>( + public static final ConfigKey GEOCODER_ID = new StringConfigKey( "geocoder.id", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider API key. Most providers require API keys. */ - public static final ConfigKey GEOCODER_KEY = new ConfigKey<>( + public static final ConfigKey GEOCODER_KEY = new StringConfigKey( "geocoder.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Language parameter for providers that support localization (e.g. Google and Nominatim). */ - public static final ConfigKey GEOCODER_LANGUAGE = new ConfigKey<>( + public static final ConfigKey GEOCODER_LANGUAGE = new StringConfigKey( "geocoder.language", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Address format string. Default value is %h %r, %t, %s, %c. See AddressFormat for more info. */ - public static final ConfigKey GEOCODER_FORMAT = new ConfigKey<>( + public static final ConfigKey GEOCODER_FORMAT = new StringConfigKey( "geocoder.format", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Cache size for geocoding results. */ - public static final ConfigKey GEOCODER_CACHE_SIZE = new ConfigKey<>( + public static final ConfigKey GEOCODER_CACHE_SIZE = new IntegerConfigKey( "geocoder.cacheSize", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Disable automatic reverse geocoding requests for all positions. */ - public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new ConfigKey<>( + public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new BooleanConfigKey( "geocoder.ignorePositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to apply reverse geocoding to invalid positions. */ - public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new ConfigKey<>( + public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "geocoder.processInvalidPositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Optional parameter to specify minimum distance for new reverse geocoding request. If distance is less than * specified value (in meters), then Traccar will reuse last known address. */ - public static final ConfigKey GEOCODER_REUSE_DISTANCE = new ConfigKey<>( + public static final ConfigKey GEOCODER_REUSE_DISTANCE = new IntegerConfigKey( "geocoder.reuseDistance", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Perform geocoding when preparing reports and sending notifications. */ - public static final ConfigKey GEOCODER_ON_REQUEST = new ConfigKey<>( + public static final ConfigKey GEOCODER_ON_REQUEST = new BooleanConfigKey( "geocoder.onRequest", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable LBS location resolution. Some devices send cell towers information and WiFi point when GPS * location is not available. Traccar can determine coordinates based on that information using third party * services. Default value is false. */ - public static final ConfigKey GEOLOCATION_ENABLE = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_ENABLE = new BooleanConfigKey( "geolocation.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider to use for LBS location. Available options: google, mozilla and opencellid. By default opencellid is * used. You have to supply a key that you get from corresponding provider. For more information see LBS geolocation * documentation. */ - public static final ConfigKey GEOLOCATION_TYPE = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_TYPE = new StringConfigKey( "geolocation.type", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Geolocation provider API URL address. Not required for most providers. */ - public static final ConfigKey GEOLOCATION_URL = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_URL = new StringConfigKey( "geolocation.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider API key. OpenCellID service requires API key. */ - public static final ConfigKey GEOLOCATION_KEY = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_KEY = new StringConfigKey( "geolocation.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to apply geolocation to invalid positions. */ - public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "geolocation.processInvalidPositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default MCC value to use if device doesn't report MCC. */ - public static final ConfigKey GEOLOCATION_MCC = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_MCC = new IntegerConfigKey( "geolocation.mcc", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default MNC value to use if device doesn't report MNC. */ - public static final ConfigKey GEOLOCATION_MNC = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_MNC = new IntegerConfigKey( "geolocation.mnc", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable speed limit API to get speed limit values depending on location. Default value is false. */ - public static final ConfigKey SPEED_LIMIT_ENABLE = new ConfigKey<>( + public static final ConfigKey SPEED_LIMIT_ENABLE = new BooleanConfigKey( "speedLimit.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider to use for speed limit. Available options: overpass. By default overpass is used. */ - public static final ConfigKey SPEED_LIMIT_TYPE = new ConfigKey<>( + public static final ConfigKey SPEED_LIMIT_TYPE = new StringConfigKey( "speedLimit.type", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Speed limit provider API URL address. */ - public static final ConfigKey SPEED_LIMIT_URL = new ConfigKey<>( + public static final ConfigKey SPEED_LIMIT_URL = new StringConfigKey( "speedLimit.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Override latitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can be * N for North or S for South. */ - public static final ConfigKey LOCATION_LATITUDE_HEMISPHERE = new ConfigKey<>( + public static final ConfigKey LOCATION_LATITUDE_HEMISPHERE = new StringConfigKey( "location.latitudeHemisphere", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Override longitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can * be E for East or W for West. */ - public static final ConfigKey LOCATION_LONGITUDE_HEMISPHERE = new ConfigKey<>( + public static final ConfigKey LOCATION_LONGITUDE_HEMISPHERE = new StringConfigKey( "location.longitudeHemisphere", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Jetty Request Log Path. @@ -1220,112 +1301,112 @@ public final class Keys { * over the file. * Example: ./logs/jetty-yyyy_mm_dd.request.log */ - public static final ConfigKey WEB_REQUEST_LOG_PATH = new ConfigKey<>( + public static final ConfigKey WEB_REQUEST_LOG_PATH = new StringConfigKey( "web.requestLog.path", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Set the number of days before rotated request log files are deleted. */ - public static final ConfigKey WEB_REQUEST_LOG_RETAIN_DAYS = new ConfigKey<>( + public static final ConfigKey WEB_REQUEST_LOG_RETAIN_DAYS = new IntegerConfigKey( "web.requestLog.retainDays", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Disable systemd health checks. */ - public static final ConfigKey WEB_DISABLE_HEALTH_CHECK = new ConfigKey<>( + public static final ConfigKey WEB_DISABLE_HEALTH_CHECK = new BooleanConfigKey( "web.disableHealthCheck", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Sets SameSite cookie attribute value. * Supported options: Lax, Strict, None. */ - public static final ConfigKey WEB_SAME_SITE_COOKIE = new ConfigKey<>( + public static final ConfigKey WEB_SAME_SITE_COOKIE = new StringConfigKey( "web.sameSiteCookie", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enables persisting Jetty session to the database */ - public static final ConfigKey WEB_PERSIST_SESSION = new ConfigKey<>( + public static final ConfigKey WEB_PERSIST_SESSION = new BooleanConfigKey( "web.persistSession", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Public URL for the web app. Used for notification and report link. * * If not provided, Traccar will attempt to get a URL from the server IP address, but it might be a local address. */ - public static final ConfigKey WEB_URL = new ConfigKey<>( + public static final ConfigKey WEB_URL = new StringConfigKey( "web.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Output logging to the standard terminal output instead of a log file. */ - public static final ConfigKey LOGGER_CONSOLE = new ConfigKey<>( + public static final ConfigKey LOGGER_CONSOLE = new BooleanConfigKey( "logger.console", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Log executed SQL queries. */ - public static final ConfigKey LOGGER_QUERIES = new ConfigKey<>( + public static final ConfigKey LOGGER_QUERIES = new BooleanConfigKey( "logger.queries", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Log file name. For rotating logs, a date is added at the end of the file name for non-current logs. */ - public static final ConfigKey LOGGER_FILE = new ConfigKey<>( + public static final ConfigKey LOGGER_FILE = new StringConfigKey( "logger.file", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Logging level. Default value is 'info'. * Available options: off, severe, warning, info, config, fine, finer, finest, all. */ - public static final ConfigKey LOGGER_LEVEL = new ConfigKey<>( + public static final ConfigKey LOGGER_LEVEL = new StringConfigKey( "logger.level", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Print full exception traces. Useful for debugging. By default shortened traces are logged. */ - public static final ConfigKey LOGGER_FULL_STACK_TRACES = new ConfigKey<>( + public static final ConfigKey LOGGER_FULL_STACK_TRACES = new BooleanConfigKey( "logger.fullStackTraces", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Create a new log file daily. Helps with log management. For example, downloading and cleaning logs. Enabled by * default. */ - public static final ConfigKey LOGGER_ROTATE = new ConfigKey<>( + public static final ConfigKey LOGGER_ROTATE = new BooleanConfigKey( "logger.rotate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * A list of position attributes to log. */ - public static final ConfigKey LOGGER_ATTRIBUTES = new ConfigKey<>( + public static final ConfigKey LOGGER_ATTRIBUTES = new StringConfigKey( "logger.attributes", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "time,position,speed,course,accuracy,result"); /** * Multicast address for broadcasting synchronization events. */ - public static final ConfigKey BROADCAST_ADDRESS = new ConfigKey<>( + public static final ConfigKey BROADCAST_ADDRESS = new StringConfigKey( "broadcast.address", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Multicast port for broadcasting synchronization events. */ - public static final ConfigKey BROADCAST_PORT = new ConfigKey<>( + public static final ConfigKey BROADCAST_PORT = new IntegerConfigKey( "broadcast.port", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 81043fd7a..a3e04f920 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -73,34 +73,6 @@ public class DeviceManager extends BaseObjectManager implements Identity refreshLastPositions(); } - @Override - public Device addUnknownDevice(String uniqueId) { - Device device = new Device(); - device.setName(uniqueId); - device.setUniqueId(uniqueId); - device.setCategory(Context.getConfig().getString(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY)); - - long defaultGroupId = Context.getConfig().getLong(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID); - if (defaultGroupId != 0) { - device.setGroupId(defaultGroupId); - } - - try { - addItem(device); - - LOGGER.info("Automatically registered device " + uniqueId); - - if (defaultGroupId != 0) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } - - return device; - } catch (StorageException e) { - LOGGER.warn("Automatic device registration error", e); - return null; - } - } - public void updateDeviceCache(boolean force) { long lastUpdate = devicesLastUpdate.get(); if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) @@ -316,35 +288,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result != null ? (String) result : defaultValue; } - @Override - public int lookupAttributeInteger( - long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); - if (result != null) { - return result instanceof String ? Integer.parseInt((String) result) : ((Number) result).intValue(); - } - return defaultValue; - } - - @Override - public long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); - if (result != null) { - return result instanceof String ? Long.parseLong((String) result) : ((Number) result).longValue(); - } - return defaultValue; - } - - public double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); - if (result != null) { - return result instanceof String ? Double.parseDouble((String) result) : ((Number) result).doubleValue(); - } - return defaultValue; - } - private Object lookupAttribute(long deviceId, String attributeName, boolean lookupServer, boolean lookupConfig) { Object result = null; Device device = getById(deviceId); diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index ee386fdfd..10a64ebd9 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -20,8 +20,6 @@ import org.traccar.model.Position; public interface IdentityManager { - Device addUnknownDevice(String uniqueId); - Device getById(long id); Device getByUniqueId(String uniqueId) throws Exception; @@ -38,13 +36,4 @@ public interface IdentityManager { String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig); - int lookupAttributeInteger( - long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig); - - long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig); - - double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig); - } diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 0511ec98b..00cbf92a0 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -21,11 +21,18 @@ import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; 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.helper.model.AttributeUtil; +import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Limit; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Date; @@ -50,11 +57,11 @@ public class FilterHandler extends BaseDataHandler { private final long skipLimit; private final boolean skipAttributes; - private final IdentityManager identityManager; - private final DataManager dataManager; + private final CacheManager cacheManager; + private final Storage storage; @Inject - public FilterHandler(Config config, IdentityManager identityManager, DataManager dataManager) { + public FilterHandler(Config config, CacheManager cacheManager, Storage storage) { enabled = config.getBoolean(Keys.FILTER_ENABLE); filterInvalid = config.getBoolean(Keys.FILTER_INVALID); filterZero = config.getBoolean(Keys.FILTER_ZERO); @@ -69,8 +76,18 @@ public class FilterHandler extends BaseDataHandler { 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; + this.cacheManager = cacheManager; + this.storage = storage; + } + + private Position getPrecedingPosition(long deviceId, Date date) throws StorageException { + return storage.getObject(Position.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Compare("fixTime", "<=", "time", date)), + new Order(true, "fixTime"), + new Limit(1))); } private boolean filterInvalid(Position position) { @@ -144,9 +161,8 @@ public class FilterHandler extends BaseDataHandler { private boolean skipAttributes(Position position) { if (skipAttributes) { - String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "filter.skipAttributes", "", false, true); - for (String attribute : attributesString.split("[ ,]")) { + String string = AttributeUtil.lookup(cacheManager, Keys.FILTER_SKIP_ATTRIBUTES, position.getDeviceId()); + for (String attribute : string.split("[ ,]")) { if (position.getAttributes().containsKey(attribute)) { return true; } @@ -183,13 +199,13 @@ public class FilterHandler extends BaseDataHandler { if (filterRelative) { try { Date newFixTime = position.getFixTime(); - preceding = dataManager.getPrecedingPosition(deviceId, newFixTime); + preceding = getPrecedingPosition(deviceId, newFixTime); } catch (StorageException e) { LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); - preceding = getLastReceivedPosition(deviceId); + preceding = cacheManager.getPosition(deviceId); } } else { - preceding = getLastReceivedPosition(deviceId); + preceding = cacheManager.getPosition(deviceId); } if (filterDuplicate(position, preceding) && !skipLimit(position, preceding) && !skipAttributes(position)) { filterType.append("Duplicate "); @@ -209,7 +225,7 @@ public class FilterHandler extends BaseDataHandler { } if (filterType.length() > 0) { - String uniqueId = identityManager.getById(deviceId).getUniqueId(); + String uniqueId = cacheManager.getObject(Device.class, deviceId).getUniqueId(); LOGGER.info("Position filtered by {}filters from device: {}", filterType, uniqueId); return true; } @@ -217,10 +233,6 @@ public class FilterHandler extends BaseDataHandler { return false; } - private Position getLastReceivedPosition(long deviceId) { - return identityManager.getLastPosition(deviceId); - } - @Override protected Position handlePosition(Position position) { if (enabled && filter(position)) { diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java index 2e3ed9d91..f760457a3 100644 --- a/src/main/java/org/traccar/handler/HemisphereHandler.java +++ b/src/main/java/org/traccar/handler/HemisphereHandler.java @@ -39,7 +39,7 @@ public class HemisphereHandler extends BaseDataHandler { latitudeFactor = -1; } } - String longitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE); + String longitudeHemisphere = config.getString(Keys.LOCATION_LONGITUDE_HEMISPHERE); if (longitudeHemisphere != null) { if (longitudeHemisphere.equalsIgnoreCase("E")) { longitudeFactor = 1; diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java index 7849abff9..2d105af3e 100644 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -16,10 +16,13 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.util.Collections; @@ -28,31 +31,28 @@ import java.util.Map; @ChannelHandler.Sharable public class FuelDropEventHandler extends BaseEventHandler { - public static final String ATTRIBUTE_FUEL_DROP_THRESHOLD = "fuelDropThreshold"; - - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public FuelDropEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public FuelDropEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device == null) { return null; } - if (!identityManager.isLatestPosition(position)) { + if (!PositionUtil.isLatest(cacheManager, position)) { return null; } - double fuelDropThreshold = identityManager - .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, true, false); - + double fuelDropThreshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); if (fuelDropThreshold > 0) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (position.getAttributes().containsKey(Position.KEY_FUEL_LEVEL) && lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_FUEL_LEVEL)) { @@ -60,7 +60,6 @@ public class FuelDropEventHandler extends BaseEventHandler { - position.getDouble(Position.KEY_FUEL_LEVEL); if (drop >= fuelDropThreshold) { Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); - event.set(ATTRIBUTE_FUEL_DROP_THRESHOLD, fuelDropThreshold); return Collections.singletonMap(event, position); } } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 45bb13be5..6de56d11e 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -23,6 +23,8 @@ import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.session.DeviceState; import org.traccar.model.Event; @@ -36,7 +38,6 @@ import javax.inject.Inject; public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED = "speed"; - public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private final DeviceManager deviceManager; private final CacheManager cacheManager; @@ -58,7 +59,7 @@ public class OverspeedEventHandler extends BaseEventHandler { Position position = deviceState.getOverspeedPosition(); Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); event.set(ATTRIBUTE_SPEED, deviceState.getOverspeedPosition().getSpeed()); - event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + event.set(Position.KEY_SPEED_LIMIT, speedLimit); event.setGeofenceId(deviceState.getOverspeedGeofenceId()); deviceState.setOverspeedState(notRepeat); deviceState.setOverspeedPosition(null); @@ -115,15 +116,15 @@ public class OverspeedEventHandler extends BaseEventHandler { protected Map analyzePosition(Position position) { long deviceId = position.getDeviceId(); - Device device = deviceManager.getById(deviceId); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device == null) { return null; } - if (!deviceManager.isLatestPosition(position) || !position.getValid()) { + if (!PositionUtil.isLatest(cacheManager, position) || !position.getValid()) { return null; } - double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, true, false); + double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); double positionSpeedLimit = position.getDouble(Position.KEY_SPEED_LIMIT); if (positionSpeedLimit > 0) { @@ -137,7 +138,7 @@ public class OverspeedEventHandler extends BaseEventHandler { for (long geofenceId : device.getGeofenceIds()) { Geofence geofence = cacheManager.getObject(Geofence.class, geofenceId); if (geofence != null) { - double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT); + double currentSpeedLimit = geofence.getDouble(Keys.EVENT_OVERSPEED_LIMIT.getKey()); if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0 || preferLowest && currentSpeedLimit < geofenceSpeedLimit || !preferLowest && currentSpeedLimit > geofenceSpeedLimit) { diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java new file mode 100644 index 000000000..5b3fc1cbe --- /dev/null +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -0,0 +1,72 @@ +/* + * 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.helper.model; + +import org.traccar.config.ConfigKey; +import org.traccar.config.KeyType; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.session.cache.CacheManager; + +public final class AttributeUtil { + + private AttributeUtil() { + } + + @SuppressWarnings({ "deprecation", "unchecked" }) + public static T lookup(CacheManager cacheManager, ConfigKey key, long deviceId) { + Device device = cacheManager.getObject(Device.class, deviceId); + Object result = device.getAttributes().get(key.getKey()); + long groupId = device.getGroupId(); + while (result == null && groupId > 0) { + Group group = cacheManager.getObject(Group.class, groupId); + if (group != null) { + result = group.getAttributes().get(key.getKey()); + } + } + if (result == null && key.hasType(KeyType.SERVER)) { + result = cacheManager.getServer().getAttributes().get(key.getKey()); + } + if (result == null && key.hasType(KeyType.CONFIG)) { + result = cacheManager.getConfig().getString(key.getKey()); + } + + if (result != null) { + Class valueClass = key.getValueClass(); + if (valueClass.equals(Boolean.class)) { + return (T) (result instanceof String + ? Boolean.parseBoolean((String) result) + : result); + } else if (valueClass.equals(Integer.class)) { + return (T) (Object) (result instanceof String + ? Integer.parseInt((String) result) + : ((Number) result).intValue()); + } else if (valueClass.equals(Long.class)) { + return (T) (Object) (result instanceof String + ? Long.parseLong((String) result) + : ((Number) result).longValue()); + } else if (valueClass.equals(Double.class)) { + return (T) (Object) (result instanceof String + ? Double.parseDouble((String) result) + : ((Number) result).doubleValue()); + } else { + return (T) result; + } + } + return key.getDefaultValue(); + } + +} diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index af33b1f5c..16a28ea79 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -38,7 +38,7 @@ public class CellTower { } public static CellTower fromLacCid(Config config, int lac, long cid) { - return from(config.getInteger(Keys.GEOLOCATION_MCC), config.getInteger(Keys.GEOLOCATION_MCC), lac, cid); + return from(config.getInteger(Keys.GEOLOCATION_MCC), config.getInteger(Keys.GEOLOCATION_MNC), lac, cid); } public static CellTower fromCidLac(Config config, long cid, int lac) { diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 0ff668fa8..aa23bfac5 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2021 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. @@ -17,6 +17,8 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; @@ -66,8 +68,9 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public String[] getFormat(long deviceId) { - return getIdentityManager().lookupAttributeString( - deviceId, getProtocolName() + ".format", format, false, false).split(","); + String value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_FORMAT.withPrefix(getProtocolName()), deviceId); + return (value != null ? value : format).split(","); } public void setFormat(String format) { @@ -75,8 +78,9 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public DateFormat getDateFormat(long deviceId) { - DateFormat dateFormat = new SimpleDateFormat(getIdentityManager().lookupAttributeString( - deviceId, getProtocolName() + ".dateFormat", this.dateFormat, false, false)); + String value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_DATE_FORMAT.withPrefix(getProtocolName()), deviceId); + DateFormat dateFormat = new SimpleDateFormat(value != null ? value : this.dateFormat); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); return dateFormat; } diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 6340def86..44ba1da38 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -20,6 +20,8 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -71,8 +73,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public int getProtocolType(long deviceId) { - return getIdentityManager().lookupAttributeInteger( - deviceId, getProtocolName() + ".protocolType", protocolType, false, true); + Integer value = AttributeUtil.lookup(getCacheManager(), Keys.PROTOCOL_TYPE, deviceId); + return value != null ? value : protocolType; } public void setHbm(boolean hbm) { @@ -80,8 +82,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isHbm(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".hbm", hbm, false, true); + Boolean value = AttributeUtil.lookup(getCacheManager(), Keys.PROTOCOL_HBM, deviceId); + return value != null ? value : hbm; } public void setIncludeAdc(boolean includeAdc) { @@ -89,8 +91,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeAdc(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeAdc", includeAdc, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_ADC.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeAdc; } public void setIncludeRpm(boolean includeRpm) { @@ -98,8 +101,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeRpm(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeRpm", includeRpm, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_RPM.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeRpm; } public void setIncludeTemp(boolean includeTemp) { @@ -107,8 +111,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeTemp(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeTemp", includeTemp, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_TEMPERATURE.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeTemp; } private Position decode9( diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 6d5fefa75..3fa467b57 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -28,6 +28,7 @@ import org.traccar.config.Keys; import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; @@ -279,9 +280,9 @@ public class ConnectionManager { result.putAll(event); } + double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); event = Main.getInjector().getInstance(OverspeedEventHandler.class) - .updateOverspeedState(deviceState, Context.getDeviceManager(). - lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false)); + .updateOverspeedState(deviceState, speedLimit); if (event != null) { result.putAll(event); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 896df83e7..87384f746 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -74,6 +74,10 @@ public class CacheManager { invalidateUsers(); } + public Config getConfig() { + return config; + } + public T getObject(Class clazz, long id) { try { lock.readLock().lock(); diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 1652a6694..add423cdd 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -9,6 +9,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.model.Device; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; +import org.traccar.session.cache.CacheManager; import java.net.SocketAddress; import java.util.HashSet; @@ -16,6 +17,7 @@ import java.util.HashSet; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -23,19 +25,18 @@ import static org.mockito.Mockito.when; public class BaseTest { protected T inject(T decoder) throws Exception { - decoder.setConfig(new Config()); + var config = new Config(); + decoder.setConfig(config); var device = mock(Device.class); when(device.getId()).thenReturn(1L); var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); when(identityManager.getByUniqueId(any())).thenReturn(device); - when(identityManager.lookupAttributeBoolean(anyLong(), any(), anyBoolean(), anyBoolean(), anyBoolean())) - .thenAnswer(invocation -> invocation.getArguments()[2]); - when(identityManager.lookupAttributeString(anyLong(), any(), any(), anyBoolean(), anyBoolean())) - .thenAnswer(invocation -> invocation.getArguments()[2]); - when(identityManager.lookupAttributeInteger(anyLong(), any(), anyInt(), anyBoolean(), anyBoolean())) - .thenAnswer(invocation -> invocation.getArguments()[2]); decoder.setIdentityManager(identityManager); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(config); + when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); + decoder.setCacheManager(cacheManager); var connectionManager = mock(ConnectionManager.class); var uniqueIdsProvided = new HashSet(); when(connectionManager.getDeviceSession(any(), any(), any(), any())).thenAnswer(invocation -> { diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java index 10d6768cf..a1102da88 100644 --- a/src/test/java/org/traccar/handler/FilterHandlerTest.java +++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java @@ -5,15 +5,16 @@ 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 org.traccar.session.cache.CacheManager; import java.util.Date; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -26,9 +27,9 @@ public class FilterHandlerTest extends BaseTest { 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); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(config); + passingHandler = new FilterHandler(config, cacheManager, null); } @Before @@ -45,11 +46,11 @@ public class FilterHandlerTest extends BaseTest { 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); + when(config.getString(Keys.FILTER_SKIP_ATTRIBUTES.getKey())).thenReturn("alarm,result"); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(config); + when(cacheManager.getObject(any(), anyLong())).thenReturn(mock(Device.class)); + filteringHandler = new FilterHandler(config, cacheManager, null); } private Position createPosition(Date time, boolean valid, double speed) { diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 9e86031e8..46e142935 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -61,7 +61,7 @@ public class OverspeedEventHandlerTest extends BaseTest { Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); assertEquals(50, event.getDouble("speed"), 0.1); - assertEquals(40, event.getDouble(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT), 0.1); + assertEquals(40, event.getDouble("speedLimit"), 0.1); assertEquals(geofenceId, event.getGeofenceId()); assertEquals(notRepeat, deviceState.getOverspeedState()); -- cgit v1.2.3 From 22bd8bcc80b850dc2308be50cf2886c39b0655da Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:08:52 -0700 Subject: Refactor device password --- src/main/java/org/traccar/BaseProtocolEncoder.java | 20 +++++++++++++++++--- src/main/java/org/traccar/config/Keys.java | 7 +++++++ .../java/org/traccar/database/DeviceManager.java | 18 ------------------ .../java/org/traccar/database/IdentityManager.java | 2 -- .../org/traccar/helper/model/AttributeUtil.java | 21 +++++++++++++++++++++ .../org/traccar/protocol/Gt06ProtocolEncoder.java | 5 +++-- .../org/traccar/protocol/LaipacProtocolDecoder.java | 5 +++-- src/test/java/org/traccar/BaseTest.java | 6 ++++-- 8 files changed, 55 insertions(+), 29 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 10b780fc8..612d91c57 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -15,7 +15,6 @@ */ package org.traccar; -import com.google.inject.Inject; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; @@ -24,7 +23,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.database.IdentityManager; import org.traccar.helper.NetworkUtil; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.session.cache.CacheManager; + +import javax.inject.Inject; public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { @@ -34,12 +37,23 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter private final Protocol protocol; + private CacheManager cacheManager; + private IdentityManager identityManager; public BaseProtocolEncoder(Protocol protocol) { this.protocol = protocol; } + public CacheManager getCacheManager() { + return cacheManager; + } + + @Inject + public void setCacheManager(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + public IdentityManager getIdentityManager() { return identityManager; } @@ -59,8 +73,8 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - String password = identityManager - .getDevicePassword(command.getDeviceId(), getProtocolName(), defaultPassword); + String password = AttributeUtil.getDevicePassword( + cacheManager, command.getDeviceId(), getProtocolName(), defaultPassword); command.set(Command.KEY_DEVICE_PASSWORD, password); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 465751d38..410947079 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -69,6 +69,13 @@ public final class Keys { ".timeout", List.of(KeyType.CONFIG)); + /** + * Device password. Commonly used in some protocol for sending commands. + */ + public static final ConfigKey DEVICE_PASSWORD = new StringConfigKey( + "devicePassword", + List.of(KeyType.DEVICE)); + /** * Device password. Commonly used in some protocol for sending commands. */ diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index a3e04f920..eee19c4c2 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -99,24 +99,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - @Override - public String getDevicePassword(long id, String protocol, String defaultPassword) { - - String password = lookupAttributeString(id, Command.KEY_DEVICE_PASSWORD, null, false, false); - if (password != null) { - return password; - } - - if (protocol != null) { - password = Context.getConfig().getString(Keys.PROTOCOL_DEVICE_PASSWORD.withPrefix(protocol)); - if (password != null) { - return password; - } - } - - return defaultPassword; - } - @Override public Set getAllItems() { Set result = super.getAllItems(); diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index 10a64ebd9..1897c637f 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -24,8 +24,6 @@ public interface IdentityManager { Device getByUniqueId(String uniqueId) throws Exception; - String getDevicePassword(long id, String protocol, String defaultPassword); - Position getLastPosition(long deviceId); boolean isLatestPosition(Position position); diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 5b3fc1cbe..225089d5c 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -15,8 +15,11 @@ */ package org.traccar.helper.model; +import org.traccar.Context; import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; +import org.traccar.config.Keys; +import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; @@ -69,4 +72,22 @@ public final class AttributeUtil { return key.getDefaultValue(); } + public static String getDevicePassword( + CacheManager cacheManager, long deviceId, String protocol, String defaultPassword) { + + String password = lookup(cacheManager, Keys.DEVICE_PASSWORD, deviceId); + if (password != null) { + return password; + } + + if (protocol != null) { + password = cacheManager.getConfig().getString(Keys.PROTOCOL_DEVICE_PASSWORD.withPrefix(protocol)); + if (password != null) { + return password; + } + } + + return defaultPassword; + } + } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 3ed828fc7..569f4a809 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; import org.traccar.helper.Checksum; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.nio.charset.StandardCharsets; @@ -68,8 +69,8 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); - String password = getIdentityManager() - .getDevicePassword(command.getDeviceId(), getProtocolName(), "123456"); + String password = AttributeUtil.getDevicePassword( + getCacheManager(), command.getDeviceId(), getProtocolName(), "123456"); switch (command.getType()) { case Command.TYPE_ENGINE_STOP: diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index c55c0624d..e9570ee11 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -17,6 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -252,8 +253,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { sendAcknowledge(status, event, checksum, channel, remoteAddress); - String devicePassword = getIdentityManager() - .getDevicePassword(deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); + String devicePassword = AttributeUtil.getDevicePassword( + getCacheManager(), deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); sendEventResponse(event, devicePassword, channel, remoteAddress); } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index add423cdd..54035553f 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -66,9 +66,11 @@ public class BaseTest { var device = mock(Device.class); when(device.getId()).thenReturn(1L); when(device.getUniqueId()).thenReturn("123456789012345"); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(mock(Config.class)); + when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); + encoder.setCacheManager(cacheManager); var identityManager = mock(IdentityManager.class); - when(identityManager.getDevicePassword(anyLong(), any(), any())) - .thenAnswer(invocation -> invocation.getArguments()[2]); when(identityManager.getById(anyLong())).thenReturn(device); when(identityManager.getByUniqueId(any())).thenReturn(device); encoder.setIdentityManager(identityManager); -- cgit v1.2.3 From 97a189c51817a6b1d7a86aece8a91ff378488799 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:27:24 -0700 Subject: Refactor attribute lookup --- src/main/java/org/traccar/config/Keys.java | 35 +++++++++++++++- .../java/org/traccar/database/DeviceManager.java | 48 ---------------------- .../java/org/traccar/database/IdentityManager.java | 8 +--- .../org/traccar/handler/CopyAttributesHandler.java | 15 +++---- .../org/traccar/protocol/Gt06ProtocolEncoder.java | 9 ++-- .../org/traccar/protocol/H02ProtocolEncoder.java | 7 +++- .../traccar/protocol/HuabaoProtocolEncoder.java | 6 ++- .../traccar/protocol/MeiligaoProtocolEncoder.java | 6 ++- .../traccar/protocol/MeitrackProtocolEncoder.java | 6 ++- .../org/traccar/protocol/T55ProtocolDecoder.java | 12 ++++-- .../org/traccar/protocol/Tk103ProtocolEncoder.java | 8 ++-- .../org/traccar/reports/StopsReportProvider.java | 3 +- .../org/traccar/reports/SummaryReportProvider.java | 3 +- .../org/traccar/reports/TripsReportProvider.java | 4 +- 14 files changed, 81 insertions(+), 89 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 410947079..5909ae517 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -124,7 +124,8 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_ACK = new BooleanConfigSuffix( ".ack", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); /** * Ignore device reported fix time. Useful in case some devices report invalid time. Currently only available for @@ -268,6 +269,22 @@ public final class Keys { "orbcomm.password", List.of(KeyType.CONFIG)); + /** + * Use alternative format for the protocol of commands. + */ + public static final ConfigSuffix PROTOCOL_ALTERNATIVE = new BooleanConfigSuffix( + ".alternative", + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); + + /** + * Protocol format includes a language field. + */ + public static final ConfigSuffix PROTOCOL_LANGUAGE = new BooleanConfigSuffix( + ".language", + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); + /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ @@ -944,6 +961,14 @@ public final class Keys { "report.trip.useIgnition", List.of(KeyType.CONFIG)); + /** + * Ignore odometer value reported by the device and use server-calculated total distance instead. This is useful + * if device reports invalid or zero odometer values. + */ + public static final ConfigKey REPORT_IGNORE_ODOMETER = new BooleanConfigKey( + "report.ignoreOdometer", + List.of(KeyType.CONFIG)); + /** * Boolean flag to enable or disable position filtering. */ @@ -1119,6 +1144,14 @@ public final class Keys { "processing.copyAttributes.enable", List.of(KeyType.CONFIG)); + /** + * List of attributes to copy. Attributes should be separated by a comma without any spacing. + * For example: alarm,ignition + */ + public static final ConfigKey PROCESSING_COPY_ATTRIBUTES = new StringConfigKey( + "processing.copyAttributes", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + /** * Enable computed attributes processing. */ diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index eee19c4c2..86334ede8 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -253,54 +253,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result; } - @Override - public boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); - if (result != null) { - return result instanceof String ? Boolean.parseBoolean((String) result) : (Boolean) result; - } - return defaultValue; - } - - @Override - public String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); - return result != null ? (String) result : defaultValue; - } - - private Object lookupAttribute(long deviceId, String attributeName, boolean lookupServer, boolean lookupConfig) { - Object result = null; - Device device = getById(deviceId); - if (device != null) { - result = device.getAttributes().get(attributeName); - if (result == null) { - long groupId = device.getGroupId(); - while (groupId > 0) { - Group group = cacheManager.getObject(Group.class, device.getGroupId()); - if (group != null) { - result = group.getAttributes().get(attributeName); - if (result != null) { - break; - } - groupId = group.getGroupId(); - } else { - groupId = 0; - } - } - } - if (result == null && lookupServer) { - Server server = cacheManager.getServer(); - result = server.getAttributes().get(attributeName); - } - if (result == null && lookupConfig) { - result = Context.getConfig().getString(attributeName); - } - } - return result; - } - public DeviceState getDeviceState(long deviceId) { DeviceState deviceState = deviceStates.get(deviceId); if (deviceState == null) { diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index 1897c637f..5ef1c8c5e 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.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. @@ -28,10 +28,4 @@ public interface IdentityManager { boolean isLatestPosition(Position position); - boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig); - - String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig); - } diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 8285dcc5d..405a52ecd 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -20,8 +20,9 @@ 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.helper.model.AttributeUtil; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -29,20 +30,20 @@ import javax.inject.Inject; public class CopyAttributesHandler extends BaseDataHandler { private final boolean enabled; - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public CopyAttributesHandler(Config config, IdentityManager identityManager) { + public CopyAttributesHandler(Config config, CacheManager cacheManager) { enabled = config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE); - this.identityManager = identityManager; + this.cacheManager = cacheManager; } @Override protected Position handlePosition(Position position) { if (enabled) { - String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "processing.copyAttributes", "", false, true); - Position last = identityManager.getLastPosition(position.getDeviceId()); + String attributesString = AttributeUtil.lookup( + cacheManager, Keys.PROCESSING_COPY_ATTRIBUTES, position.getDeviceId()); + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { for (String attribute : attributesString.split("[ ,]")) { if (last.getAttributes().containsKey(attribute) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 569f4a809..e1c17710b 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; @@ -33,8 +34,8 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, String content) { - boolean language = getIdentityManager() - .lookupAttributeBoolean(deviceId, getProtocolName() + ".language", false, false, true); + boolean language = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_LANGUAGE.withPrefix(getProtocolName()), deviceId); ByteBuf buf = Unpooled.buffer(); @@ -66,8 +67,8 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); String password = AttributeUtil.getDevicePassword( getCacheManager(), command.getDeviceId(), getProtocolName(), "123456"); diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 7fca0f93e..86b8c80d4 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -18,6 +18,8 @@ package org.traccar.protocol; import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.util.Date; @@ -58,8 +60,9 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { return formatCommand(time, uniqueId, "S20", "1", "0"); case Command.TYPE_POSITION_PERIODIC: String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); - if (getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true)) { + if (AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), + command.getDeviceId())) { return formatCommand(time, uniqueId, "D1", frequency); } else { return formatCommand(time, uniqueId, "S71", "22", frequency); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java index 82cf03b51..ada7e3fba 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -19,7 +19,9 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.DataConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.text.SimpleDateFormat; @@ -34,8 +36,8 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); ByteBuf id = Unpooled.wrappedBuffer( DataConverter.parseHex(getUniqueId(command.getDeviceId()))); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index 7784ab093..21f9f8801 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -19,8 +19,10 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.nio.charset.StandardCharsets; @@ -58,8 +60,8 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); int outputControlMessageType = alternative ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java index 799e14ea2..365dbb35a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -17,7 +17,9 @@ package org.traccar.protocol; import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.util.Map; @@ -41,8 +43,8 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { Map attributes = command.getAttributes(); - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); switch (command.getType()) { case Command.TYPE_POSITION_SINGLE: diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 3d892c021..409c7e768 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -17,6 +17,8 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -128,10 +130,12 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { private Position decodeGprmc( DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { - if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) - && getIdentityManager().lookupAttributeBoolean( - deviceSession.getDeviceId(), getProtocolName() + ".ack", false, false, true)) { - channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); + if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel)) { + boolean ack = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ACK.withPrefix(getProtocolName()), deviceSession.getDeviceId()); + if (ack) { + channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); + } } Parser parser = new Parser(PATTERN_GPRMC, sentence); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java index a0e9b199c..e3e1ae961 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -18,6 +18,8 @@ package org.traccar.protocol; import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; public class Tk103ProtocolEncoder extends StringProtocolEncoder { @@ -41,12 +43,12 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = forceAlternative || getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); initDevicePassword(command, "123456"); - if (alternative) { + if (alternative || forceAlternative) { switch (command.getType()) { case Command.TYPE_CUSTOM: return formatAlt(command, "%s", Command.KEY_DATA); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index a63d7ee21..192d7a0f7 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -57,8 +57,7 @@ public class StopsReportProvider { } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); return reportUtils.detectTripsAndStops( PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, StopReportItem.class); } diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 86d76b4e3..f3a9786b9 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -74,8 +74,7 @@ public class SummaryReportProvider { result.setMaxSpeed(position.getSpeed()); } } - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); result.setDistance(PositionUtil.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); result.setSpentFuel(reportUtils.calculateFuel(firstPosition, previousPosition)); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index bec4c39fd..928609b9e 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -57,9 +57,7 @@ public class TripsReportProvider { } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); return reportUtils.detectTripsAndStops( PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, TripReportItem.class); } -- cgit v1.2.3 From 182656b6dc1fb5d167bb752c16ecf633add001a8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:37:21 -0700 Subject: Remove unused code --- src/main/java/org/traccar/Context.java | 2 - .../org/traccar/database/BaseObjectManager.java | 4 -- .../java/org/traccar/database/DeviceManager.java | 74 +--------------------- .../java/org/traccar/database/IdentityManager.java | 2 - .../org/traccar/helper/model/AttributeUtil.java | 2 - src/test/java/org/traccar/BaseTest.java | 2 - 6 files changed, 2 insertions(+), 84 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 9e8e3c521..854af97c0 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -25,7 +25,6 @@ import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.session.ConnectionManager; -import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; public final class Context { @@ -70,7 +69,6 @@ public final class Context { deviceManager = new DeviceManager( config, - Main.getInjector().getInstance(CacheManager.class), Main.getInjector().getInstance(DataManager.class), Main.getInjector().getInstance(ConnectionManager.class)); diff --git a/src/main/java/org/traccar/database/BaseObjectManager.java b/src/main/java/org/traccar/database/BaseObjectManager.java index dd8b3bae4..c94053985 100644 --- a/src/main/java/org/traccar/database/BaseObjectManager.java +++ b/src/main/java/org/traccar/database/BaseObjectManager.java @@ -67,10 +67,6 @@ public class BaseObjectManager { return dataManager; } - protected final Class getBaseClass() { - return baseClass; - } - public T getById(long itemId) { try { readLock(); diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 86334ede8..841915f1c 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -20,14 +20,10 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.model.Command; import org.traccar.model.Device; -import org.traccar.model.Group; import org.traccar.model.Position; -import org.traccar.model.Server; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; -import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import java.util.Collection; @@ -43,12 +39,9 @@ public class DeviceManager extends BaseObjectManager implements Identity private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); - private final Config config; - private final CacheManager cacheManager; private final ConnectionManager connectionManager; private final long dataRefreshDelay; - private Map devicesByUniqueId; private final AtomicLong devicesLastUpdate = new AtomicLong(); private final Map positions = new ConcurrentHashMap<>(); @@ -56,19 +49,9 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map deviceStates = new ConcurrentHashMap<>(); public DeviceManager( - Config config, CacheManager cacheManager, DataManager dataManager, ConnectionManager connectionManager) { + Config config, DataManager dataManager, ConnectionManager connectionManager) { super(dataManager, Device.class); - this.config = config; - this.cacheManager = cacheManager; this.connectionManager = connectionManager; - try { - writeLock(); - if (devicesByUniqueId == null) { - devicesByUniqueId = new ConcurrentHashMap<>(); - } - } finally { - writeUnlock(); - } dataRefreshDelay = config.getLong(Keys.DATABASE_REFRESH_DELAY) * 1000; refreshLastPositions(); } @@ -81,24 +64,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - @Override - public Device getByUniqueId(String uniqueId) { - boolean forceUpdate; - try { - readLock(); - forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean(Keys.DATABASE_IGNORE_UNKNOWN); - } finally { - readUnlock(); - } - updateDeviceCache(forceUpdate); - try { - readLock(); - return devicesByUniqueId.get(uniqueId); - } finally { - readUnlock(); - } - } - @Override public Set getAllItems() { Set result = super.getAllItems(); @@ -132,35 +97,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - private void addByUniqueId(Device device) { - try { - writeLock(); - if (devicesByUniqueId == null) { - devicesByUniqueId = new ConcurrentHashMap<>(); - } - devicesByUniqueId.put(device.getUniqueId(), device); - } finally { - writeUnlock(); - } - } - - private void removeByUniqueId(String deviceUniqueId) { - try { - writeLock(); - if (devicesByUniqueId != null) { - devicesByUniqueId.remove(deviceUniqueId); - } - } finally { - writeUnlock(); - } - } - - @Override - protected void addNewItem(Device device) { - super.addNewItem(device); - addByUniqueId(device); - } - @Override protected void updateCachedItem(Device device) { Device cachedDevice = getById(device.getId()); @@ -172,20 +108,14 @@ public class DeviceManager extends BaseObjectManager implements Identity cachedDevice.setModel(device.getModel()); cachedDevice.setDisabled(device.getDisabled()); cachedDevice.setAttributes(device.getAttributes()); - if (!device.getUniqueId().equals(cachedDevice.getUniqueId())) { - removeByUniqueId(cachedDevice.getUniqueId()); - cachedDevice.setUniqueId(device.getUniqueId()); - addByUniqueId(cachedDevice); - } + cachedDevice.setUniqueId(device.getUniqueId()); } @Override protected void removeCachedItem(long deviceId) { Device cachedDevice = getById(deviceId); if (cachedDevice != null) { - String deviceUniqueId = cachedDevice.getUniqueId(); super.removeCachedItem(deviceId); - removeByUniqueId(deviceUniqueId); } positions.remove(deviceId); } diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index 5ef1c8c5e..b42d4c292 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -22,8 +22,6 @@ public interface IdentityManager { Device getById(long id); - Device getByUniqueId(String uniqueId) throws Exception; - Position getLastPosition(long deviceId); boolean isLatestPosition(Position position); diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 225089d5c..58b922d95 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -15,11 +15,9 @@ */ package org.traccar.helper.model; -import org.traccar.Context; import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; import org.traccar.config.Keys; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 54035553f..6db568300 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -31,7 +31,6 @@ public class BaseTest { when(device.getId()).thenReturn(1L); var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); - when(identityManager.getByUniqueId(any())).thenReturn(device); decoder.setIdentityManager(identityManager); var cacheManager = mock(CacheManager.class); when(cacheManager.getConfig()).thenReturn(config); @@ -72,7 +71,6 @@ public class BaseTest { encoder.setCacheManager(cacheManager); var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); - when(identityManager.getByUniqueId(any())).thenReturn(device); encoder.setIdentityManager(identityManager); return encoder; } -- cgit v1.2.3 From ddbe4d7de6ae7590e2b927066312597efa129393 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 11:08:32 -0700 Subject: Remove positions from manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 2 +- src/main/java/org/traccar/Context.java | 4 +- src/main/java/org/traccar/MainEventHandler.java | 28 ++++++- src/main/java/org/traccar/MainModule.java | 4 +- src/main/java/org/traccar/api/AsyncSocket.java | 14 +++- .../java/org/traccar/api/AsyncSocketServlet.java | 7 +- .../org/traccar/api/resource/PositionResource.java | 14 +--- .../java/org/traccar/database/DataManager.java | 24 +----- .../java/org/traccar/database/DeviceManager.java | 93 +--------------------- .../java/org/traccar/database/IdentityManager.java | 5 -- .../java/org/traccar/handler/DistanceHandler.java | 10 +-- .../org/traccar/handler/EngineHoursHandler.java | 10 +-- .../java/org/traccar/handler/GeocoderHandler.java | 11 ++- .../traccar/handler/events/AlertEventHandler.java | 10 +-- .../handler/events/BehaviorEventHandler.java | 10 +-- .../traccar/handler/events/DriverEventHandler.java | 18 ++--- .../handler/events/IgnitionEventHandler.java | 15 ++-- .../handler/events/MaintenanceEventHandler.java | 3 +- .../traccar/handler/events/MotionEventHandler.java | 12 +-- .../org/traccar/helper/model/PositionUtil.java | 17 ++++ .../org/traccar/reports/common/ReportUtils.java | 2 +- .../org/traccar/handler/DistanceHandlerTest.java | 4 +- .../handler/events/AlertEventHandlerTest.java | 4 +- .../handler/events/IgnitionEventHandlerTest.java | 4 +- 24 files changed, 122 insertions(+), 203 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 076b52e96..f7e726f02 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -156,7 +156,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { if (position.getDeviceId() != 0) { position.setOutdated(true); - Position last = identityManager.getLastPosition(position.getDeviceId()); + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { position.setFixTime(last.getFixTime()); position.setValid(last.getValid()); diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 854af97c0..c549b20c2 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -24,7 +24,6 @@ import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.session.ConnectionManager; import org.traccar.storage.Storage; public final class Context { @@ -69,8 +68,7 @@ public final class Context { deviceManager = new DeviceManager( config, - Main.getInjector().getInstance(DataManager.class), - Main.getInjector().getInstance(ConnectionManager.class)); + Main.getInjector().getInstance(DataManager.class)); identityManager = deviceManager; diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 7fff2e13f..e1aee3cc8 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -28,10 +28,16 @@ import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.helper.NetworkUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Arrays; @@ -46,10 +52,15 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Set connectionlessProtocols = new HashSet<>(); private final Set logAttributes = new LinkedHashSet<>(); + private final CacheManager cacheManager; + private final Storage storage; private final ConnectionManager connectionManager; @Inject - public MainEventHandler(Config config, ConnectionManager connectionManager) { + public MainEventHandler( + Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager) { + this.cacheManager = cacheManager; + this.storage = storage; this.connectionManager = connectionManager; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { @@ -64,8 +75,19 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { Position position = (Position) msg; try { - Context.getDeviceManager().updateLatestPosition(position); - Main.getInjector().getInstance(CacheManager.class).updatePosition(position); + if (PositionUtil.isLatest(cacheManager, position)) { + Device device = new Device(); + device.setId(position.getDeviceId()); + device.setPositionId(position.getId()); + storage.updateObject(device, new Request( + new Columns.Include("positionId"), + new Condition.Equals("id", "id"))); + + cacheManager.updatePosition(position); + cacheManager.getObject(Device.class, position.getDeviceId()).setPositionId(position.getId()); + + connectionManager.updatePosition(position); + } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a9337a3a2..a7e531808 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -252,9 +252,9 @@ public class MainModule extends AbstractModule { @Provides public static GeocoderHandler provideGeocoderHandler( - Config config, @Nullable Geocoder geocoder, IdentityManager identityManager) { + Config config, @Nullable Geocoder geocoder, CacheManager cacheManager) { if (geocoder != null) { - return new GeocoderHandler(config, geocoder, identityManager); + return new GeocoderHandler(config, geocoder, cacheManager); } return null; } diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index 3239d36c4..40aa68e88 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -21,11 +21,13 @@ import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.helper.model.PositionUtil; import org.traccar.session.ConnectionManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import java.util.Collection; import java.util.Collections; @@ -42,11 +44,13 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private final ObjectMapper objectMapper; private final ConnectionManager connectionManager; + private final Storage storage; private final long userId; - public AsyncSocket(ObjectMapper objectMapper, ConnectionManager connectionManager, long userId) { + public AsyncSocket(ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage, long userId) { this.objectMapper = objectMapper; this.connectionManager = connectionManager; + this.storage = storage; this.userId = userId; } @@ -55,7 +59,11 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U super.onWebSocketConnect(session); Map> data = new HashMap<>(); - data.put(KEY_POSITIONS, Context.getDeviceManager().getInitialState(userId)); + try { + data.put(KEY_POSITIONS, PositionUtil.getLatestPositions(storage, userId)); + } catch (StorageException e) { + throw new RuntimeException(e); + } sendData(data); connectionManager.addListener(userId, this); diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 7c532179b..7d9fdf0ed 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -22,6 +22,7 @@ import org.traccar.Context; import org.traccar.api.resource.SessionResource; import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; +import org.traccar.storage.Storage; import javax.inject.Inject; import javax.inject.Singleton; @@ -33,11 +34,13 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { private final ObjectMapper objectMapper; private final ConnectionManager connectionManager; + private final Storage storage; @Inject - public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager) { + public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage) { this.objectMapper = objectMapper; this.connectionManager = connectionManager; + this.storage = storage; } @Override @@ -46,7 +49,7 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(objectMapper, connectionManager, userId); + return new AsyncSocket(objectMapper, connectionManager, storage, userId); } else { return null; } diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 099d97632..cac64feb1 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -17,10 +17,8 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; import org.traccar.helper.model.PositionUtil; -import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Position; -import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -37,7 +35,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.stream.Collectors; @Path("positions") @Produces(MediaType.APPLICATION_JSON) @@ -68,16 +65,7 @@ public class PositionResource extends BaseResource { new Columns.All(), new Condition.LatestPositions(deviceId))); } } else { - var devices = storage.getObjects(Device.class, new Request( - new Columns.Include("id"), - new Condition.Permission(User.class, getUserId(), Device.class))); - var deviceIds = devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet()); - - var positions = storage.getObjects(Position.class, new Request( - new Columns.All(), new Condition.LatestPositions())); - return positions.stream() - .filter(position -> deviceIds.contains(position.getDeviceId())) - .collect(Collectors.toList()); + return PositionUtil.getLatestPositions(storage, getUserId()); } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index aa600e375..f80f429e1 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -24,20 +24,17 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; -import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Collection; -import java.util.Date; public class DataManager { private final Storage storage; @Inject - public DataManager(Storage storage) throws Exception { + public DataManager(Storage storage) { this.storage = storage; } @@ -47,25 +44,6 @@ public class DataManager { new Condition.Equals("id", "id"))); } - public Position getPrecedingPosition(long deviceId, Date date) throws StorageException { - return storage.getObject(Position.class, new Request( - new Columns.All(), - new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), - new Condition.Compare("fixTime", "<=", "time", date)), - new Order(true, "fixTime"), - new Limit(1))); - } - - public void updateLatestPosition(Position position) throws StorageException { - Device device = new Device(); - device.setId(position.getDeviceId()); - device.setPositionId(position.getId()); - storage.updateObject(device, new Request( - new Columns.Include("positionId"), - new Condition.Equals("id", "id"))); - } - public Collection getLatestPositions() throws StorageException { return storage.getObjects(Position.class, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 841915f1c..4516255c1 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,21 +15,13 @@ */ package org.traccar.database; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.storage.StorageException; import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -37,23 +29,15 @@ import java.util.concurrent.atomic.AtomicLong; public class DeviceManager extends BaseObjectManager implements IdentityManager { - private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); - - private final ConnectionManager connectionManager; private final long dataRefreshDelay; private final AtomicLong devicesLastUpdate = new AtomicLong(); - private final Map positions = new ConcurrentHashMap<>(); - private final Map deviceStates = new ConcurrentHashMap<>(); - public DeviceManager( - Config config, DataManager dataManager, ConnectionManager connectionManager) { + public DeviceManager(Config config, DataManager dataManager) { super(dataManager, Device.class); - this.connectionManager = connectionManager; dataRefreshDelay = config.getLong(Keys.DATABASE_REFRESH_DELAY) * 1000; - refreshLastPositions(); } public void updateDeviceCache(boolean force) { @@ -78,25 +62,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return getItems(getAllItems()); } - public Set getAllUserItems(long userId) { - return Context.getPermissionsManager().getDevicePermissions(userId); - } - - public Set getUserItems(long userId) { - if (Context.getPermissionsManager() != null) { - Set result = new HashSet<>(); - for (long deviceId : Context.getPermissionsManager().getDevicePermissions(userId)) { - Device device = getById(deviceId); - if (device != null && !device.getDisabled()) { - result.add(deviceId); - } - } - return result; - } else { - return new HashSet<>(); - } - } - @Override protected void updateCachedItem(Device device) { Device cachedDevice = getById(device.getId()); @@ -117,7 +82,6 @@ public class DeviceManager extends BaseObjectManager implements Identity if (cachedDevice != null) { super.removeCachedItem(deviceId); } - positions.remove(deviceId); } public void updateDeviceStatus(Device device) throws StorageException { @@ -128,61 +92,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - private void refreshLastPositions() { - if (getDataManager() != null) { - try { - for (Position position : getDataManager().getLatestPositions()) { - positions.put(position.getDeviceId(), position); - } - } catch (StorageException error) { - LOGGER.warn("Load latest positions error", error); - } - } - } - - public boolean isLatestPosition(Position position) { - Position lastPosition = getLastPosition(position.getDeviceId()); - return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; - } - - public void updateLatestPosition(Position position) throws StorageException { - - if (isLatestPosition(position)) { - - getDataManager().updateLatestPosition(position); - - Device device = getById(position.getDeviceId()); - if (device != null) { - device.setPositionId(position.getId()); - } - - positions.put(position.getDeviceId(), position); - - connectionManager.updatePosition(position); - } - } - - @Override - public Position getLastPosition(long deviceId) { - return positions.get(deviceId); - } - - public Collection getInitialState(long userId) { - - List result = new LinkedList<>(); - - if (Context.getPermissionsManager() != null) { - for (long deviceId : Context.getPermissionsManager().getUserAdmin(userId) - ? getAllUserItems(userId) : getUserItems(userId)) { - if (positions.containsKey(deviceId)) { - result.add(positions.get(deviceId)); - } - } - } - - return result; - } - public DeviceState getDeviceState(long deviceId) { DeviceState deviceState = deviceStates.get(deviceId); if (deviceState == null) { diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index b42d4c292..1e0eb00c5 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -16,14 +16,9 @@ package org.traccar.database; import org.traccar.model.Device; -import org.traccar.model.Position; public interface IdentityManager { Device getById(long id); - Position getLastPosition(long deviceId); - - boolean isLatestPosition(Position position); - } diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index 08c8c068d..fb82b5d8e 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -20,9 +20,9 @@ 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.helper.DistanceCalculator; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.math.BigDecimal; @@ -31,15 +31,15 @@ import java.math.RoundingMode; @ChannelHandler.Sharable public class DistanceHandler extends BaseDataHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final boolean filter; private final int coordinatesMinError; private final int coordinatesMaxError; @Inject - public DistanceHandler(Config config, IdentityManager identityManager) { - this.identityManager = identityManager; + public DistanceHandler(Config config, CacheManager cacheManager) { + this.cacheManager = cacheManager; this.filter = config.getBoolean(Keys.COORDINATES_FILTER); this.coordinatesMinError = config.getInteger(Keys.COORDINATES_MIN_ERROR); this.coordinatesMaxError = config.getInteger(Keys.COORDINATES_MAX_ERROR); @@ -54,7 +54,7 @@ public class DistanceHandler extends BaseDataHandler { } double totalDistance = 0.0; - Position last = identityManager != null ? identityManager.getLastPosition(position.getDeviceId()) : null; + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { totalDistance = last.getDouble(Position.KEY_TOTAL_DISTANCE); if (!position.getAttributes().containsKey(Position.KEY_DISTANCE)) { diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index be2a46ade..bfffdcb0c 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -18,25 +18,25 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; -import org.traccar.database.IdentityManager; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class EngineHoursHandler extends BaseDataHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public EngineHoursHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public EngineHoursHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Position handlePosition(Position position) { if (!position.getAttributes().containsKey(Position.KEY_HOURS)) { - Position last = identityManager.getLastPosition(position.getDeviceId()); + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { long hours = last.getLong(Position.KEY_HOURS); if (last.getBoolean(Position.KEY_IGNITION) && position.getBoolean(Position.KEY_IGNITION)) { diff --git a/src/main/java/org/traccar/handler/GeocoderHandler.java b/src/main/java/org/traccar/handler/GeocoderHandler.java index 075bdf815..0248fca05 100644 --- a/src/main/java/org/traccar/handler/GeocoderHandler.java +++ b/src/main/java/org/traccar/handler/GeocoderHandler.java @@ -22,9 +22,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.geocoder.Geocoder; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; @ChannelHandler.Sharable public class GeocoderHandler extends ChannelInboundHandlerAdapter { @@ -32,15 +32,14 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(GeocoderHandler.class); private final Geocoder geocoder; - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final boolean ignorePositions; private final boolean processInvalidPositions; private final int geocoderReuseDistance; - public GeocoderHandler( - Config config, Geocoder geocoder, IdentityManager identityManager) { + public GeocoderHandler(Config config, Geocoder geocoder, CacheManager cacheManager) { this.geocoder = geocoder; - this.identityManager = identityManager; + this.cacheManager = cacheManager; ignorePositions = config.getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); @@ -52,7 +51,7 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { final Position position = (Position) message; if (processInvalidPositions || position.getValid()) { if (geocoderReuseDistance != 0) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && lastPosition.getAddress() != null && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) { position.setAddress(lastPosition.getAddress()); diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java index 6e7b0b16e..75626ca6c 100644 --- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -21,21 +21,21 @@ import java.util.Map; import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class AlertEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final boolean ignoreDuplicateAlerts; @Inject - public AlertEventHandler(Config config, IdentityManager identityManager) { - this.identityManager = identityManager; + public AlertEventHandler(Config config, CacheManager cacheManager) { + this.cacheManager = cacheManager; ignoreDuplicateAlerts = config.getBoolean(Keys.EVENT_IGNORE_DUPLICATE_ALERTS); } @@ -45,7 +45,7 @@ public class AlertEventHandler extends BaseEventHandler { if (alarm != null) { boolean ignoreAlert = false; if (ignoreDuplicateAlerts) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && alarm.equals(lastPosition.getAttributes().get(Position.KEY_ALARM))) { ignoreAlert = true; } diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java index bbf749cdc..3c2fa6a97 100644 --- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java @@ -18,10 +18,10 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.util.Collections; @@ -33,19 +33,19 @@ public class BehaviorEventHandler extends BaseEventHandler { private final double accelerationThreshold; private final double brakingThreshold; - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public BehaviorEventHandler(Config config, IdentityManager identityManager) { + public BehaviorEventHandler(Config config, CacheManager cacheManager) { accelerationThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_ACCELERATION_THRESHOLD); brakingThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_BRAKING_THRESHOLD); - this.identityManager = identityManager; + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && position.getFixTime().equals(lastPosition.getFixTime())) { double acceleration = UnitsConverter.mpsFromKnots(position.getSpeed() - lastPosition.getSpeed()) * 1000 / (position.getFixTime().getTime() - lastPosition.getFixTime().getTime()); diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java index 510ac3465..1ad66ba64 100644 --- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -16,35 +16,35 @@ */ package org.traccar.handler.events; -import java.util.Collections; -import java.util.Map; - import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; @ChannelHandler.Sharable public class DriverEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public DriverEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public DriverEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - if (!identityManager.isLatestPosition(position)) { + if (!PositionUtil.isLatest(cacheManager, position)) { return null; } String driverUniqueId = position.getString(Position.KEY_DRIVER_UNIQUE_ID); if (driverUniqueId != null) { String oldDriverUniqueId = null; - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null) { oldDriverUniqueId = lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); } diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 9887c9db6..6e411539c 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -20,27 +20,28 @@ import java.util.Collections; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class IgnitionEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public IgnitionEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public IgnitionEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); - if (device == null || !identityManager.isLatestPosition(position)) { + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); + if (device == null || !PositionUtil.isLatest(cacheManager, position)) { return null; } @@ -49,7 +50,7 @@ public class IgnitionEventHandler extends BaseEventHandler { if (position.getAttributes().containsKey(Position.KEY_IGNITION)) { boolean ignition = position.getBoolean(Position.KEY_IGNITION); - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_IGNITION)) { boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION); diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index f85aab043..be3e9bf8d 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; @@ -40,7 +39,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { @Override protected Map analyzePosition(Position position) { - Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) < 0) { return null; } diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 2c381e530..724e9bf15 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -18,13 +18,13 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; import org.traccar.session.DeviceState; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.util.Collections; @@ -33,13 +33,13 @@ import java.util.Map; @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final DeviceManager deviceManager; private final TripsConfig tripsConfig; @Inject - public MotionEventHandler(IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { - this.identityManager = identityManager; + public MotionEventHandler(CacheManager cacheManager, DeviceManager deviceManager, TripsConfig tripsConfig) { + this.cacheManager = cacheManager; this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; } @@ -113,11 +113,11 @@ public class MotionEventHandler extends BaseEventHandler { protected Map analyzePosition(Position position) { long deviceId = position.getDeviceId(); - Device device = identityManager.getById(deviceId); + Device device = cacheManager.getObject(Device.class, deviceId); if (device == null) { return null; } - if (!identityManager.isLatestPosition(position) + if (!PositionUtil.isLatest(cacheManager, position) || !tripsConfig.getProcessInvalidPositions() && !position.getValid()) { return null; } diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 566e31bc5..31f828947 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -15,7 +15,10 @@ */ package org.traccar.helper.model; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -26,6 +29,7 @@ import org.traccar.storage.query.Request; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; public final class PositionUtil { @@ -60,4 +64,17 @@ public final class PositionUtil { new Order("fixTime"))); } + public static List getLatestPositions(Storage storage, long userId) throws StorageException { + var devices = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, userId, Device.class))); + var deviceIds = devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet()); + + var positions = storage.getObjects(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions())); + return positions.stream() + .filter(position -> deviceIds.contains(position.getDeviceId())) + .collect(Collectors.toList()); + } + } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 84866a67b..bb37bfa9c 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -346,7 +346,7 @@ public class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); + MotionEventHandler motionHandler = new MotionEventHandler(null, deviceManager, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; diff --git a/src/test/java/org/traccar/handler/DistanceHandlerTest.java b/src/test/java/org/traccar/handler/DistanceHandlerTest.java index f7c6e42cd..a18b14edd 100644 --- a/src/test/java/org/traccar/handler/DistanceHandlerTest.java +++ b/src/test/java/org/traccar/handler/DistanceHandlerTest.java @@ -3,15 +3,17 @@ package org.traccar.handler; import org.junit.Test; import org.traccar.config.Config; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; public class DistanceHandlerTest { @Test public void testCalculateDistance() { - DistanceHandler distanceHandler = new DistanceHandler(new Config(), null); + DistanceHandler distanceHandler = new DistanceHandler(new Config(), mock(CacheManager.class)); Position position = distanceHandler.handlePosition(new Position()); diff --git a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java index d6cf32ca3..550a93da3 100644 --- a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java @@ -3,9 +3,9 @@ package org.traccar.handler.events; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; -import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import java.util.Map; @@ -18,7 +18,7 @@ public class AlertEventHandlerTest extends BaseTest { @Test public void testAlertEventHandler() { - AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), mock(IdentityManager.class)); + AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), mock(CacheManager.class)); Position position = new Position(); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); diff --git a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java index 0de80dd70..84898bea0 100644 --- a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java @@ -2,9 +2,9 @@ package org.traccar.handler.events; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import java.util.Map; @@ -16,7 +16,7 @@ public class IgnitionEventHandlerTest extends BaseTest { @Test public void testIgnitionEventHandler() { - IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(mock(IdentityManager.class)); + IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(mock(CacheManager.class)); Position position = new Position(); position.set(Position.KEY_IGNITION, true); -- cgit v1.2.3 From 03b50c61afd7c9d7e19a76feb261147dd0f69588 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 11:44:40 -0700 Subject: Remove identity manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 11 ------ src/main/java/org/traccar/BaseProtocolEncoder.java | 15 +------- src/main/java/org/traccar/Context.java | 9 ----- src/main/java/org/traccar/MainEventHandler.java | 14 +++---- src/main/java/org/traccar/MainModule.java | 6 --- src/main/java/org/traccar/WebDataHandler.java | 10 ++--- .../traccar/api/resource/AttributeResource.java | 4 +- .../java/org/traccar/database/DeviceManager.java | 2 +- .../java/org/traccar/database/IdentityManager.java | 24 ------------ .../traccar/handler/ComputedAttributesHandler.java | 8 +--- .../traccar/protocol/CastelProtocolEncoder.java | 4 +- .../traccar/protocol/GalileoProtocolDecoder.java | 3 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 7 +--- .../traccar/protocol/MeiligaoProtocolDecoder.java | 3 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 3 +- .../traccar/protocol/PretraceProtocolEncoder.java | 2 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 3 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 8 ++-- .../org/traccar/reports/EventsReportProvider.java | 3 +- .../org/traccar/reports/RouteReportProvider.java | 3 +- .../org/traccar/reports/StopsReportProvider.java | 3 +- .../org/traccar/reports/SummaryReportProvider.java | 6 +-- .../org/traccar/reports/TripsReportProvider.java | 3 +- .../org/traccar/reports/common/ReportUtils.java | 18 +++++---- src/test/java/org/traccar/BaseTest.java | 9 ----- src/test/java/org/traccar/WebDataHandlerTest.java | 8 ++-- .../traccar/handler/ComputedAttributesTest.java | 2 +- .../java/org/traccar/reports/ReportUtilsTest.java | 43 +++++++++++----------- 28 files changed, 75 insertions(+), 159 deletions(-) delete mode 100644 src/main/java/org/traccar/database/IdentityManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index f7e726f02..382daf92f 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; -import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; @@ -47,7 +46,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final Protocol protocol; - private IdentityManager identityManager; private CacheManager cacheManager; private ConnectionManager connectionManager; private StatisticsManager statisticsManager; @@ -58,15 +56,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.protocol = protocol; } - public IdentityManager getIdentityManager() { - return identityManager; - } - - @Inject - public void setIdentityManager(IdentityManager identityManager) { - this.identityManager = identityManager; - } - public CacheManager getCacheManager() { return cacheManager; } diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 612d91c57..bc1180a08 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -21,10 +21,10 @@ import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.database.IdentityManager; import org.traccar.helper.NetworkUtil; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.model.Device; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -39,8 +39,6 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter private CacheManager cacheManager; - private IdentityManager identityManager; - public BaseProtocolEncoder(Protocol protocol) { this.protocol = protocol; } @@ -54,21 +52,12 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter this.cacheManager = cacheManager; } - public IdentityManager getIdentityManager() { - return identityManager; - } - - @Inject - public void setIdentityManager(IdentityManager identityManager) { - this.identityManager = identityManager; - } - public String getProtocolName() { return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; } protected String getUniqueId(long deviceId) { - return identityManager.getById(deviceId).getUniqueId(); + return cacheManager.getObject(Device.class, deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index c549b20c2..45d075912 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -19,7 +19,6 @@ import org.traccar.config.Config; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; @@ -37,12 +36,6 @@ public final class Context { return config; } - private static IdentityManager identityManager; - - public static IdentityManager getIdentityManager() { - return identityManager; - } - private static DeviceManager deviceManager; public static DeviceManager getDeviceManager() { @@ -70,8 +63,6 @@ public final class Context { config, Main.getInjector().getInstance(DataManager.class)); - identityManager = deviceManager; - permissionsManager = new PermissionsManager( Main.getInjector().getInstance(DataManager.class), Main.getInjector().getInstance(Storage.class)); diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index e1aee3cc8..d2665cbcc 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -74,12 +74,14 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (msg instanceof Position) { Position position = (Position) msg; + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); + try { if (PositionUtil.isLatest(cacheManager, position)) { - Device device = new Device(); - device.setId(position.getDeviceId()); - device.setPositionId(position.getId()); - storage.updateObject(device, new Request( + Device updatedDevice = new Device(); + updatedDevice.setId(position.getDeviceId()); + updatedDevice.setPositionId(position.getId()); + storage.updateObject(updatedDevice, new Request( new Columns.Include("positionId"), new Condition.Equals("id", "id"))); @@ -92,11 +94,9 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.warn("Failed to update device", error); } - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); - StringBuilder builder = new StringBuilder(); builder.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); - builder.append("id: ").append(uniqueId); + builder.append("id: ").append(device.getUniqueId()); for (String attribute : logAttributes) { switch (attribute) { case "time": diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a7e531808..d57ee5d38 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -31,7 +31,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; @@ -108,11 +107,6 @@ public class MainModule extends AbstractModule { return Context.getConfig(); } - @Provides - public static IdentityManager provideIdentityManager() { - return Context.getIdentityManager(); - } - @Provides public static Client provideClient() { return ClientBuilder.newClient().register( diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index db99ecaf8..192a15bcf 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -26,7 +26,6 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.helper.Checksum; import org.traccar.model.Device; import org.traccar.model.Position; @@ -62,7 +61,6 @@ public class WebDataHandler extends BaseDataHandler { private static final String KEY_DEVICE = "device"; private final CacheManager cacheManager; - private final IdentityManager identityManager; private final ObjectMapper objectMapper; private final Client client; @@ -80,11 +78,9 @@ public class WebDataHandler extends BaseDataHandler { @Inject public WebDataHandler( - Config config, CacheManager cacheManager, IdentityManager identityManager, - ObjectMapper objectMapper, Client client) { + Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client) { this.cacheManager = cacheManager; - this.identityManager = identityManager; this.objectMapper = objectMapper; this.client = client; this.url = config.getString(Keys.FORWARD_URL); @@ -138,7 +134,7 @@ public class WebDataHandler extends BaseDataHandler { public String formatRequest(Position position) throws UnsupportedEncodingException, JsonProcessingException { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); String request = url .replace("{name}", URLEncoder.encode(device.getName(), StandardCharsets.UTF_8.name())) @@ -302,7 +298,7 @@ public class WebDataHandler extends BaseDataHandler { private Map prepareJsonPayload(Position position) { Map data = new HashMap<>(); - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); data.put(KEY_POSITION, position); diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index 43d8a7ccd..fb74b9bbe 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -28,7 +28,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; import org.traccar.config.Config; import org.traccar.model.Attribute; @@ -62,8 +61,7 @@ public class AttributeResource extends ExtendedObjectResource { new Columns.All(), new Condition.LatestPositions(deviceId))); - Object result = new ComputedAttributesHandler(config, Context.getIdentityManager(), null) - .computeAttribute(entity, position); + Object result = new ComputedAttributesHandler(config, null).computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { case "number": diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 4516255c1..d6c442f10 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -27,7 +27,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -public class DeviceManager extends BaseObjectManager implements IdentityManager { +public class DeviceManager extends BaseObjectManager { private final long dataRefreshDelay; diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java deleted file mode 100644 index 1e0eb00c5..000000000 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - * 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.database; - -import org.traccar.model.Device; - -public interface IdentityManager { - - Device getById(long id); - -} diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index bec3d38e0..82ac4e804 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; @@ -47,7 +46,6 @@ public class ComputedAttributesHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ComputedAttributesHandler.class); - private final IdentityManager identityManager; private final CacheManager cacheManager; private final JexlEngine engine; @@ -55,9 +53,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private final boolean includeDeviceAttributes; @Inject - public ComputedAttributesHandler( - Config config, IdentityManager identityManager, CacheManager cacheManager) { - this.identityManager = identityManager; + public ComputedAttributesHandler(Config config, CacheManager cacheManager) { this.cacheManager = cacheManager; engine = new JexlEngine(); engine.setStrict(true); @@ -68,7 +64,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private MapContext prepareContext(Position position) { MapContext result = new MapContext(); if (includeDeviceAttributes) { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device != null) { for (Object key : device.getAttributes().keySet()) { result.set((String) key, device.getAttributes().get(key)); diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java index 0fb4bf8b4..61dde3e80 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 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. @@ -33,7 +33,7 @@ public class CastelProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(0); - String uniqueId = getIdentityManager().getById(deviceId).getUniqueId(); + String uniqueId = getUniqueId(deviceId); buf.writeByte('@'); buf.writeByte('@'); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index a2ba7b029..bf14d47e0 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -320,14 +320,13 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 4b9757874..c53fbfe5a 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -31,7 +31,6 @@ import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; -import org.traccar.model.Device; import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; @@ -1026,8 +1025,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = getIdentityManager().getById(deviceSession.getDeviceId()); - position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photos.remove(pictureId).release(); } @@ -1262,8 +1260,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date(timestamp)); - Device device = getIdentityManager().getById(deviceSession.getDeviceId()); - position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photos.remove(mediaId).release(); } } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index 0b6bf8663..f3b56973a 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -468,10 +468,9 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } else if (command == MSG_POSITION_IMAGE) { byte imageIndex = buf.readByte(); buf.readUnsignedByte(); // image upload type - String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); ByteBuf photo = photos.remove(imageIndex); try { - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); } finally { photo.release(); } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 30689436d..87459d3fc 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.model.Device; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -203,7 +204,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); } - String deviceModel = getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); + String deviceModel = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); if (deviceModel == null) { deviceModel = ""; } diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java index 106ba9537..a109e7a07 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java @@ -34,7 +34,7 @@ public class PretraceProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - String uniqueId = getIdentityManager().getById(command.getDeviceId()).getUniqueId(); + String uniqueId = getUniqueId(command.getDeviceId()); switch (command.getType()) { case Command.TYPE_CUSTOM: diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index 21b91203f..2a6a81a65 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -174,14 +174,13 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index f91eef837..77047fe26 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -119,7 +119,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { return printable; } - private void decodeSerial(Channel channel, SocketAddress remoteAddress, Position position, ByteBuf buf) { + private void decodeSerial( + Channel channel, SocketAddress remoteAddress, DeviceSession deviceSession, Position position, ByteBuf buf) { getLastLocation(position, null); @@ -148,10 +149,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { channel, remoteAddress, photoId, photo.writerIndex(), Math.min(IMAGE_PACKET_MAX, photo.writableBytes())); } else { - String uniqueId = getIdentityManager().getById(position.getDeviceId()).getUniqueId(); photos.remove(photoId); try { - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); } finally { photo.release(); } @@ -601,7 +601,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { ByteBufUtil.hexDump(buf.readSlice(length))); } } else if (codec == CODEC_12) { - decodeSerial(channel, remoteAddress, position, buf); + decodeSerial(channel, remoteAddress, deviceSession, position, buf); } else { decodeLocation(position, buf, codec); } diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 4db842fdb..69d95d1be 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Device; @@ -133,7 +132,7 @@ public class EventsReportProvider { } } DeviceReportSection deviceEvents = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index b4401bc87..2364cc0f3 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; @@ -79,7 +78,7 @@ public class RouteReportProvider { for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { var positions = PositionUtil.getPositions(storage, deviceId, from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 192d7a0f7..3b1f3c1fe 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; @@ -86,7 +85,7 @@ public class StopsReportProvider { for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Collection stops = detectStops(deviceId, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index f3a9786b9..1f136adeb 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.jxls.util.JxlsHelper; -import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -58,10 +57,11 @@ public class SummaryReportProvider { this.storage = storage; } - private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { + private SummaryReportItem calculateSummaryResult( + long deviceId, Collection positions) throws StorageException { SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + result.setDeviceName(reportUtils.getDevice(deviceId).getName()); if (positions != null && !positions.isEmpty()) { Position firstPosition = null; Position previousPosition = null; diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 928609b9e..95612ab30 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; @@ -85,7 +84,7 @@ public class TripsReportProvider { for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Collection trips = detectTrips(deviceId, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index bb37bfa9c..ab009161f 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,7 +31,6 @@ import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.geocoder.Geocoder; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; @@ -74,7 +73,6 @@ public class ReportUtils { private final Config config; private final Storage storage; private final PermissionsService permissionsService; - private final IdentityManager identityManager; private final DeviceManager deviceManager; private final TripsConfig tripsConfig; private final VelocityEngine velocityEngine; @@ -82,13 +80,12 @@ public class ReportUtils { @Inject public ReportUtils( - Config config, Storage storage, PermissionsService permissionsService, IdentityManager identityManager, + Config config, Storage storage, PermissionsService permissionsService, DeviceManager deviceManager, TripsConfig tripsConfig, VelocityEngine velocityEngine, @Nullable Geocoder geocoder) { this.config = config; this.storage = storage; this.permissionsService = permissionsService; - this.identityManager = identityManager; this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; this.velocityEngine = velocityEngine; @@ -104,6 +101,12 @@ public class ReportUtils { new Condition.Permission(User.class, userId, clazz)))); } + public Device getDevice(long deviceId) throws StorageException { + return storage.getObject(Device.class, new Request( + new Columns.Include("id"), + new Condition.Equals("id", "id", deviceId))); + } + public void checkPeriodLimit(Date from, Date to) { long limit = config.getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { @@ -212,7 +215,7 @@ public class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(identityManager.getById(deviceId).getName()); + trip.setDeviceName(getDevice(deviceId).getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -259,7 +262,8 @@ public class ReportUtils { } private StopReportItem calculateStop( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { + ArrayList positions, int startIndex, int endIndex, + boolean ignoreOdometer) throws StorageException { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -268,7 +272,7 @@ public class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(identityManager.getById(deviceId).getName()); + stop.setDeviceName(getDevice(deviceId).getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 6db568300..c784150dd 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -3,7 +3,6 @@ package org.traccar; import io.netty.channel.Channel; import org.traccar.config.Config; import org.traccar.database.CommandsManager; -import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.model.Device; @@ -14,8 +13,6 @@ import org.traccar.session.cache.CacheManager; import java.net.SocketAddress; import java.util.HashSet; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; @@ -29,9 +26,6 @@ public class BaseTest { decoder.setConfig(config); var device = mock(Device.class); when(device.getId()).thenReturn(1L); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); - decoder.setIdentityManager(identityManager); var cacheManager = mock(CacheManager.class); when(cacheManager.getConfig()).thenReturn(config); when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); @@ -69,9 +63,6 @@ public class BaseTest { when(cacheManager.getConfig()).thenReturn(mock(Config.class)); when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); encoder.setCacheManager(cacheManager); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); - encoder.setIdentityManager(identityManager); return encoder; } diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index ff9c80ce6..1e6e1214f 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -3,13 +3,13 @@ package org.traccar; import org.junit.Test; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -28,10 +28,10 @@ public class WebDataHandlerTest extends ProtocolTest { when(device.getName()).thenReturn("test"); when(device.getUniqueId()).thenReturn("123456789012345"); when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); - WebDataHandler handler = new WebDataHandler(config, mock(CacheManager.class), identityManager, null, null); + WebDataHandler handler = new WebDataHandler(config, cacheManager, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", diff --git a/src/test/java/org/traccar/handler/ComputedAttributesTest.java b/src/test/java/org/traccar/handler/ComputedAttributesTest.java index e3886317c..2668c4f14 100644 --- a/src/test/java/org/traccar/handler/ComputedAttributesTest.java +++ b/src/test/java/org/traccar/handler/ComputedAttributesTest.java @@ -14,7 +14,7 @@ public class ComputedAttributesTest { @Test public void testComputedAttributes() { - ComputedAttributesHandler handler = new ComputedAttributesHandler(new Config(), null, null); + ComputedAttributesHandler handler = new ComputedAttributesHandler(new Config(), null); Date date = new Date(); Position position = new Position(); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 1440c4c30..c7f2a2cc6 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -1,20 +1,21 @@ package org.traccar.reports; import org.apache.velocity.app.VelocityEngine; +import org.junit.Before; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.reports.common.TripsConfig; import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import java.text.DateFormat; import java.text.ParseException; @@ -30,11 +31,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class ReportUtilsTest extends BaseTest { + + private Storage storage; + + @Before + public void init() throws StorageException { + storage = mock(Storage.class); + when(storage.getObject(any(), any())).thenReturn(mock(Device.class)); + } private Date date(String time) throws ParseException { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @@ -53,15 +62,7 @@ public class ReportUtilsTest extends BaseTest { return position; } - - private IdentityManager mockIdentityManager() { - var device = mock(Device.class); - when(device.getName()).thenReturn("test"); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); - return identityManager; - } - + @Test public void testCalculateDistance() { Position startPosition = new Position(); @@ -77,7 +78,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testCalculateSpentFuel() { ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), mock(TripsConfig.class), mock(VelocityEngine.class), null); Position startPosition = new Position(); Position endPosition = new Position(); @@ -102,7 +103,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -157,7 +158,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -228,7 +229,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -279,7 +280,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -308,7 +309,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -337,7 +338,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -366,7 +367,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -391,7 +392,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); -- cgit v1.2.3 From 895e89504ff0ef6fe05e2a74847f9aa582a9d270 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 11:55:35 -0700 Subject: Remove unused code --- src/main/java/org/traccar/Context.java | 3 +-- .../java/org/traccar/database/PermissionsManager.java | 18 +----------------- 2 files changed, 2 insertions(+), 19 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 45d075912..dba0357c9 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -64,8 +64,7 @@ public final class Context { Main.getInjector().getInstance(DataManager.class)); permissionsManager = new PermissionsManager( - Main.getInjector().getInstance(DataManager.class), - Main.getInjector().getInstance(Storage.class)); + Main.getInjector().getInstance(DataManager.class)); } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 9d1e5aadf..0ff20775a 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -40,7 +40,6 @@ public class PermissionsManager { private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class); private final DataManager dataManager; - private final Storage storage; private final ReadWriteLock lock = new ReentrantReadWriteLock(); @@ -49,9 +48,8 @@ public class PermissionsManager { private final Map> deviceUsers = new HashMap<>(); private final Map> groupDevices = new HashMap<>(); - public PermissionsManager(DataManager dataManager, Storage storage) { + public PermissionsManager(DataManager dataManager) { this.dataManager = dataManager; - this.storage = storage; refreshDeviceAndGroupPermissions(); } @@ -71,15 +69,6 @@ public class PermissionsManager { lock.writeLock().unlock(); } - public User getUser(long userId) { - try { - return storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); - } catch (StorageException e) { - throw new RuntimeException(e); - } - } - public Set getGroupPermissions(long userId) { readLock(); try { @@ -174,11 +163,6 @@ public class PermissionsManager { } } - public boolean getUserAdmin(long userId) { - User user = getUser(userId); - return user != null && user.getAdministrator(); - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) -- cgit v1.2.3 From 24140619789c88d96364673240b172bbd2ae2c82 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:22:21 -0700 Subject: Refactor reports dependencies --- src/main/java/org/traccar/Context.java | 1 - .../org/traccar/database/PermissionsManager.java | 4 -- .../org/traccar/reports/EventsReportProvider.java | 11 ++--- .../org/traccar/reports/RouteReportProvider.java | 11 ++--- .../org/traccar/reports/StopsReportProvider.java | 11 ++--- .../org/traccar/reports/SummaryReportProvider.java | 7 ++-- .../org/traccar/reports/TripsReportProvider.java | 11 ++--- .../org/traccar/reports/common/ReportUtils.java | 49 +++++++++++++++------- 8 files changed, 54 insertions(+), 51 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index dba0357c9..5f555858d 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -23,7 +23,6 @@ import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.storage.Storage; public final class Context { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 0ff20775a..c52c72c4d 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -22,11 +22,7 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; import java.util.HashMap; import java.util.HashSet; diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 69d95d1be..878c0265d 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -73,11 +73,10 @@ public class EventsReportProvider { long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection events = getEvents(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Event event : events) { if (all || types.contains(event.getType())) { @@ -98,14 +97,13 @@ public class EventsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection events = getEvents(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { Event event = iterator.next(); @@ -132,7 +130,6 @@ public class EventsReportProvider { } } DeviceReportSection deviceEvents = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 2364cc0f3..0f618822e 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -58,11 +58,10 @@ public class RouteReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - result.addAll(PositionUtil.getPositions(storage, deviceId, from, to)); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + result.addAll(PositionUtil.getPositions(storage, device.getId(), from, to)); } return result; } @@ -71,14 +70,12 @@ public class RouteReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - var positions = PositionUtil.getPositions(storage, deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 3b1f3c1fe..6e4cd74d6 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -65,11 +65,10 @@ public class StopsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - result.addAll(detectStops(deviceId, from, to)); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + result.addAll(detectStops(device.getId(), from, to)); } return result; } @@ -78,14 +77,12 @@ public class StopsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection stops = detectStops(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection stops = detectStops(device.getId(), from, to); DeviceReportSection deviceStops = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 1f136adeb..26d79c899 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -23,6 +23,7 @@ import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; @@ -145,11 +146,11 @@ public class SummaryReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection deviceResults = + calculateSummaryResults(userId, device.getId(), from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { result.add(summaryReport); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 95612ab30..7d10879b7 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -64,11 +64,10 @@ public class TripsReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - result.addAll(detectTrips(deviceId, from, to)); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + result.addAll(detectTrips(device.getId(), from, to)); } return result; } @@ -77,14 +76,12 @@ public class TripsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection trips = detectTrips(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection trips = detectTrips(device.getId(), from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index ab009161f..3960546e9 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -26,7 +26,6 @@ import org.jxls.formula.StandardFormulaProcessor; import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; -import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -62,11 +61,14 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; -import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; public class ReportUtils { @@ -114,22 +116,39 @@ public class ReportUtils { } } - public void checkPermissions( + public Collection getAccessibleDevices( long userId, Collection deviceIds, Collection groupIds) throws StorageException { - for (long deviceId : deviceIds) { - permissionsService.checkPermission(Device.class, userId, deviceId); - } - for (long groupId : groupIds) { - permissionsService.checkPermission(Group.class, userId, groupId); - } - } - public Collection getDeviceList(Collection deviceIds, Collection groupIds) { - Collection result = new LinkedHashSet<>(deviceIds); - for (long groupId : groupIds) { - result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); + var devices = storage.getObjects(Device.class, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, Device.class))); + var deviceById = devices.stream() + .collect(Collectors.toUnmodifiableMap(Device::getId, x -> x)); + var devicesByGroup = devices.stream() + .filter(x -> x.getGroupId() > 0) + .collect(Collectors.groupingBy(Device::getGroupId)); + + var groups = storage.getObjects(Group.class, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, Group.class))); + var groupsByGroup = groups.stream() + .filter(x -> x.getGroupId() > 0) + .collect(Collectors.groupingBy(Group::getGroupId)); + + var results = deviceIds.stream() + .map(deviceById::get) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + var groupQueue = new LinkedList<>(groupIds); + while (!groupQueue.isEmpty()) { + long groupId = groupQueue.pop(); + results.addAll(devicesByGroup.getOrDefault(groupId, Collections.emptyList())); + groupQueue.addAll(groupsByGroup.getOrDefault(groupId, Collections.emptyList()) + .stream().map(Group::getId).collect(Collectors.toUnmodifiableList())); } - return result; + + return results; } public double calculateFuel(Position firstPosition, Position lastPosition) { -- cgit v1.2.3 From b23ca6de800be9f2bbedcc4109a65f06bb245713 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:26:22 -0700 Subject: Remove permissions manager --- src/main/java/org/traccar/Context.java | 10 -- .../java/org/traccar/api/BaseObjectResource.java | 7 - .../traccar/api/resource/PermissionsResource.java | 13 +- .../org/traccar/database/PermissionsManager.java | 171 --------------------- .../org/traccar/session/ConnectionManager.java | 10 +- 5 files changed, 5 insertions(+), 206 deletions(-) delete mode 100644 src/main/java/org/traccar/database/PermissionsManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 5f555858d..246ed9f02 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -19,7 +19,6 @@ import org.traccar.config.Config; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -41,12 +40,6 @@ public final class Context { return deviceManager; } - private static PermissionsManager permissionsManager; - - public static PermissionsManager getPermissionsManager() { - return permissionsManager; - } - public static void init(String configFile) throws Exception { try { @@ -62,9 +55,6 @@ public final class Context { config, Main.getInjector().getInstance(DataManager.class)); - permissionsManager = new PermissionsManager( - Main.getInjector().getInstance(DataManager.class)); - } public static BaseObjectManager getManager(Class clazz) { diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 78aa12dbe..abfed9682 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -80,9 +80,6 @@ public abstract class BaseObjectResource extends BaseResour cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); - if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } return Response.ok(entity).build(); } @@ -115,9 +112,6 @@ public abstract class BaseObjectResource extends BaseResour LogAction.edit(getUserId(), entity); - if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } return Response.ok(entity).build(); } @@ -141,7 +135,6 @@ public abstract class BaseObjectResource extends BaseResour if (baseClass.equals(Group.class)) { Context.getDeviceManager().updateDeviceCache(true); } - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index b92e6e9d9..7174a3eff 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -16,7 +16,6 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Permission; @@ -46,7 +45,7 @@ public class PermissionsResource extends BaseResource { @Inject private CacheManager cacheManager; - private void checkPermission(Permission permission, boolean link) throws StorageException { + private void checkPermission(Permission permission) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -70,16 +69,13 @@ public class PermissionsResource extends BaseResource { checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); - checkPermission(permission, true); + checkPermission(permission); storage.addPermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } - if (!entities.isEmpty()) { - Context.getPermissionsManager().refreshPermissions(new Permission(entities.get(0))); - } return Response.noContent().build(); } @@ -95,16 +91,13 @@ public class PermissionsResource extends BaseResource { checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); - checkPermission(permission, false); + checkPermission(permission); storage.removePermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } - if (!entities.isEmpty()) { - Context.getPermissionsManager().refreshPermissions(new Permission(entities.get(0))); - } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java deleted file mode 100644 index c52c72c4d..000000000 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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. - * 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.database; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -public class PermissionsManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class); - - private final DataManager dataManager; - - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final Map> groupPermissions = new HashMap<>(); - private final Map> devicePermissions = new HashMap<>(); - private final Map> deviceUsers = new HashMap<>(); - private final Map> groupDevices = new HashMap<>(); - - public PermissionsManager(DataManager dataManager) { - this.dataManager = dataManager; - refreshDeviceAndGroupPermissions(); - } - - protected final void readLock() { - lock.readLock().lock(); - } - - protected final void readUnlock() { - lock.readLock().unlock(); - } - - protected final void writeLock() { - lock.writeLock().lock(); - } - - protected final void writeUnlock() { - lock.writeLock().unlock(); - } - - public Set getGroupPermissions(long userId) { - readLock(); - try { - if (!groupPermissions.containsKey(userId)) { - groupPermissions.put(userId, new HashSet<>()); - } - return groupPermissions.get(userId); - } finally { - readUnlock(); - } - } - - public Set getDevicePermissions(long userId) { - readLock(); - try { - if (!devicePermissions.containsKey(userId)) { - devicePermissions.put(userId, new HashSet<>()); - } - return devicePermissions.get(userId); - } finally { - readUnlock(); - } - } - - private Set getAllDeviceUsers(long deviceId) { - readLock(); - try { - if (!deviceUsers.containsKey(deviceId)) { - deviceUsers.put(deviceId, new HashSet<>()); - } - return deviceUsers.get(deviceId); - } finally { - readUnlock(); - } - } - - public Set getGroupDevices(long groupId) { - readLock(); - try { - if (!groupDevices.containsKey(groupId)) { - groupDevices.put(groupId, new HashSet<>()); - } - return groupDevices.get(groupId); - } finally { - readUnlock(); - } - } - - public final void refreshDeviceAndGroupPermissions() { - writeLock(); - try { - groupPermissions.clear(); - devicePermissions.clear(); - try { - var groups = dataManager.getObjects(Group.class); - GroupTree groupTree = new GroupTree(groups, Context.getDeviceManager().getAllDevices()); - for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { - Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); - Set userDevicePermissions = getDevicePermissions(groupPermission.getOwnerId()); - userGroupPermissions.add(groupPermission.getPropertyId()); - for (Group group : groupTree.getGroups(groupPermission.getPropertyId())) { - userGroupPermissions.add(group.getId()); - } - for (Device device : groupTree.getDevices(groupPermission.getPropertyId())) { - userDevicePermissions.add(device.getId()); - } - } - - for (Permission devicePermission : dataManager.getPermissions(User.class, Device.class)) { - getDevicePermissions(devicePermission.getOwnerId()).add(devicePermission.getPropertyId()); - } - - groupDevices.clear(); - for (var group : groups) { - for (Device device : groupTree.getDevices(group.getId())) { - getGroupDevices(group.getId()).add(device.getId()); - } - } - - } catch (StorageException | ClassNotFoundException error) { - LOGGER.warn("Refresh device permissions error", error); - } - - deviceUsers.clear(); - for (Map.Entry> entry : devicePermissions.entrySet()) { - for (long deviceId : entry.getValue()) { - getAllDeviceUsers(deviceId).add(entry.getKey()); - } - } - } finally { - writeUnlock(); - } - } - - public void refreshPermissions(Permission permission) { - if (permission.getOwnerClass().equals(User.class)) { - if (permission.getPropertyClass().equals(Device.class) - || permission.getPropertyClass().equals(Group.class)) { - refreshDeviceAndGroupPermissions(); - } - } - } - -} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 3fa467b57..38d82e848 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -164,16 +164,10 @@ public class ConnectionManager { try { device.setId(storage.addObject(device, new Request(new Columns.Exclude("id")))); - - LOGGER.info("Automatically registered device " + uniqueId); - - if (defaultGroupId != 0) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } - + LOGGER.info("Automatically registered " + uniqueId); return device; } catch (StorageException e) { - LOGGER.warn("Automatic device registration error", e); + LOGGER.warn("Automatic registration failed", e); return null; } } -- cgit v1.2.3 From 3f1c4e293f7d7d267a64fa9561fe77e9ba02477b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:26:47 -0700 Subject: Remove unused code --- src/main/java/org/traccar/database/DataManager.java | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index f80f429e1..bfc79eb77 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -17,8 +17,6 @@ package org.traccar.database; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Permission; -import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -44,21 +42,10 @@ public class DataManager { new Condition.Equals("id", "id"))); } - public Collection getLatestPositions() throws StorageException { - return storage.getObjects(Position.class, new Request( - new Columns.All(), - new Condition.LatestPositions())); - } - public Server getServer() throws StorageException { return storage.getObject(Server.class, new Request(new Columns.All())); } - public Collection getPermissions(Class owner, Class property) - throws StorageException, ClassNotFoundException { - return storage.getPermissions(owner, property); - } - public Collection getObjects(Class clazz) throws StorageException { return storage.getObjects(clazz, new Request(new Columns.All())); } -- cgit v1.2.3 From 589582c7ecc0d1cd5321cb6e9f4b823284369498 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:30:26 -0700 Subject: Simplify storage interface --- .../java/org/traccar/api/security/PermissionsService.java | 4 +++- src/main/java/org/traccar/storage/Storage.java | 12 ------------ 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index f39ded2b7..ea7a9d572 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -100,7 +100,9 @@ public class PermissionsService { } else if (clazz.equals(Device.class)) { denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly(); if (addition) { - int deviceCount = storage.getPermissions(User.class, userId, Device.class).size(); + int deviceCount = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, userId, Device.class))).size(); denied = deviceCount >= getUser(userId).getDeviceLimit(); } } else if (clazz.equals(Command.class)) { diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 62dba0165..55f5c22c0 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -45,18 +45,6 @@ public abstract class Storage { return getPermissions(ownerClass, 0, propertyClass, 0); } - public List getPermissions( - Class ownerClass, long ownerId, - Class propertyClass) throws StorageException { - return getPermissions(ownerClass, ownerId, propertyClass, 0); - } - - public List getPermissions( - Class ownerClass, - Class propertyClass, long propertyId) throws StorageException { - return getPermissions(ownerClass, 0, propertyClass, propertyId); - } - public T getObject(Class clazz, Request request) throws StorageException { var objects = getObjects(clazz, request); return objects.isEmpty() ? null : objects.get(0); -- cgit v1.2.3 From 3a293661cd2900c115cfea6037c02d659c57aa52 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:19:53 -0700 Subject: Move device status --- src/main/java/org/traccar/Context.java | 4 +-- src/main/java/org/traccar/config/Keys.java | 8 ----- .../java/org/traccar/database/DataManager.java | 7 ---- .../java/org/traccar/database/DeviceManager.java | 41 ++-------------------- .../traccar/handler/events/MotionEventHandler.java | 13 +++---- .../handler/events/OverspeedEventHandler.java | 12 +++---- .../org/traccar/reports/common/ReportUtils.java | 8 ++--- .../schedule/TaskDeviceInactivityCheck.java | 30 +++++++++++----- .../org/traccar/session/ConnectionManager.java | 17 +++++++-- .../java/org/traccar/reports/ReportUtilsTest.java | 18 +++++----- 10 files changed, 62 insertions(+), 96 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 246ed9f02..c89d39f4c 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -51,9 +51,7 @@ public final class Context { throw e; } - deviceManager = new DeviceManager( - config, - Main.getInjector().getInstance(DataManager.class)); + deviceManager = new DeviceManager(Main.getInjector().getInstance(DataManager.class)); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 5909ae517..6eb61607e 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -476,14 +476,6 @@ public final class Keys { "database.registerUnknown.defaultGroupId", List.of(KeyType.CONFIG)); - /** - * Minimum device refresh timeout in seconds. Default timeout is 5 minutes. - */ - public static final ConfigKey DATABASE_REFRESH_DELAY = new LongConfigKey( - "database.refreshDelay", - List.of(KeyType.CONFIG), - 300L); - /** * Store empty messages as positions. For example, heartbeats. */ diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index bfc79eb77..398c63892 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -16,7 +16,6 @@ package org.traccar.database; import org.traccar.model.BaseModel; -import org.traccar.model.Device; import org.traccar.model.Server; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -36,12 +35,6 @@ public class DataManager { this.storage = storage; } - public void updateDeviceStatus(Device device) throws StorageException { - storage.updateObject(device, new Request( - new Columns.Include("lastUpdate"), - new Condition.Equals("id", "id"))); - } - public Server getServer() throws StorageException { return storage.getObject(Server.class, new Request(new Columns.All())); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index d6c442f10..7a472c2d4 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,34 +15,22 @@ */ package org.traccar.database; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.Device; -import org.traccar.session.DeviceState; -import org.traccar.storage.StorageException; -import java.util.Collection; -import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; public class DeviceManager extends BaseObjectManager { - private final long dataRefreshDelay; - private final AtomicLong devicesLastUpdate = new AtomicLong(); - private final Map deviceStates = new ConcurrentHashMap<>(); - - public DeviceManager(Config config, DataManager dataManager) { + public DeviceManager(DataManager dataManager) { super(dataManager, Device.class); - dataRefreshDelay = config.getLong(Keys.DATABASE_REFRESH_DELAY) * 1000; } public void updateDeviceCache(boolean force) { long lastUpdate = devicesLastUpdate.get(); - if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) + if ((force || System.currentTimeMillis() - lastUpdate > 300000L) && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { refreshItems(); } @@ -58,10 +46,6 @@ public class DeviceManager extends BaseObjectManager { return result; } - public Collection getAllDevices() { - return getItems(getAllItems()); - } - @Override protected void updateCachedItem(Device device) { Device cachedDevice = getById(device.getId()); @@ -84,25 +68,4 @@ public class DeviceManager extends BaseObjectManager { } } - public void updateDeviceStatus(Device device) throws StorageException { - getDataManager().updateDeviceStatus(device); - Device cachedDevice = getById(device.getId()); - if (cachedDevice != null) { - cachedDevice.setStatus(device.getStatus()); - } - } - - public DeviceState getDeviceState(long deviceId) { - DeviceState deviceState = deviceStates.get(deviceId); - if (deviceState == null) { - deviceState = new DeviceState(); - deviceStates.put(deviceId, deviceState); - } - return deviceState; - } - - public void setDeviceState(long deviceId, DeviceState deviceState) { - deviceStates.put(deviceId, deviceState); - } - } diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 724e9bf15..bc9d5f722 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -17,12 +17,12 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; -import org.traccar.database.DeviceManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.session.cache.CacheManager; @@ -34,13 +34,14 @@ import java.util.Map; public class MotionEventHandler extends BaseEventHandler { private final CacheManager cacheManager; - private final DeviceManager deviceManager; + private final ConnectionManager connectionManager; private final TripsConfig tripsConfig; @Inject - public MotionEventHandler(CacheManager cacheManager, DeviceManager deviceManager, TripsConfig tripsConfig) { + public MotionEventHandler( + CacheManager cacheManager, ConnectionManager connectionManager, TripsConfig tripsConfig) { this.cacheManager = cacheManager; - this.deviceManager = deviceManager; + this.connectionManager = connectionManager; this.tripsConfig = tripsConfig; } @@ -123,14 +124,14 @@ public class MotionEventHandler extends BaseEventHandler { } Map result = null; - DeviceState deviceState = deviceManager.getDeviceState(deviceId); + DeviceState deviceState = connectionManager.getDeviceState(deviceId); if (deviceState.getMotionState() == null) { deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); } else { result = updateMotionState(deviceState, position); } - deviceManager.setDeviceState(deviceId, deviceState); + connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 6de56d11e..7f3675308 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -22,10 +22,10 @@ import java.util.Map; import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; import org.traccar.helper.model.AttributeUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -39,7 +39,7 @@ public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED = "speed"; - private final DeviceManager deviceManager; + private final ConnectionManager connectionManager; private final CacheManager cacheManager; private final boolean notRepeat; @@ -47,8 +47,8 @@ public class OverspeedEventHandler extends BaseEventHandler { private final boolean preferLowest; @Inject - public OverspeedEventHandler(Config config, DeviceManager deviceManager, CacheManager cacheManager) { - this.deviceManager = deviceManager; + public OverspeedEventHandler(Config config, ConnectionManager connectionManager, CacheManager cacheManager) { + this.connectionManager = connectionManager; this.cacheManager = cacheManager; notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT); minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; @@ -157,7 +157,7 @@ public class OverspeedEventHandler extends BaseEventHandler { } Map result = null; - DeviceState deviceState = deviceManager.getDeviceState(deviceId); + DeviceState deviceState = connectionManager.getDeviceState(deviceId); if (deviceState.getOverspeedState() == null) { deviceState.setOverspeedState(position.getSpeed() > speedLimit); @@ -166,7 +166,7 @@ public class OverspeedEventHandler extends BaseEventHandler { result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); } - deviceManager.setDeviceState(deviceId, deviceState); + connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 3960546e9..f5f2cd3df 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -29,7 +29,6 @@ import org.jxls.util.TransformerFactory; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; import org.traccar.geocoder.Geocoder; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; @@ -75,7 +74,6 @@ public class ReportUtils { private final Config config; private final Storage storage; private final PermissionsService permissionsService; - private final DeviceManager deviceManager; private final TripsConfig tripsConfig; private final VelocityEngine velocityEngine; private final Geocoder geocoder; @@ -83,12 +81,10 @@ public class ReportUtils { @Inject public ReportUtils( Config config, Storage storage, PermissionsService permissionsService, - DeviceManager deviceManager, TripsConfig tripsConfig, VelocityEngine velocityEngine, - @Nullable Geocoder geocoder) { + TripsConfig tripsConfig, VelocityEngine velocityEngine, @Nullable Geocoder geocoder) { this.config = config; this.storage = storage; this.permissionsService = permissionsService; - this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; this.velocityEngine = velocityEngine; this.geocoder = geocoder; @@ -369,7 +365,7 @@ public class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(null, deviceManager, tripsConfig); + MotionEventHandler motionHandler = new MotionEventHandler(null, null, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index f2ed3c3b3..57c64dc5b 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java @@ -15,11 +15,16 @@ */ package org.traccar.schedule; -import org.traccar.database.DeviceManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.database.NotificationManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.HashMap; @@ -29,18 +34,20 @@ import java.util.concurrent.TimeUnit; public class TaskDeviceInactivityCheck implements ScheduleTask { + private static final Logger LOGGER = LoggerFactory.getLogger(TaskDeviceInactivityCheck.class); + public static final String ATTRIBUTE_DEVICE_INACTIVITY_START = "deviceInactivityStart"; public static final String ATTRIBUTE_DEVICE_INACTIVITY_PERIOD = "deviceInactivityPeriod"; public static final String ATTRIBUTE_LAST_UPDATE = "lastUpdate"; private static final long CHECK_PERIOD_MINUTES = 15; - private final DeviceManager deviceManager; + private final Storage storage; private final NotificationManager notificationManager; @Inject - public TaskDeviceInactivityCheck(DeviceManager deviceManager, NotificationManager notificationManager) { - this.deviceManager = deviceManager; + public TaskDeviceInactivityCheck(Storage storage, NotificationManager notificationManager) { + this.storage = storage; this.notificationManager = notificationManager; } @@ -55,12 +62,17 @@ public class TaskDeviceInactivityCheck implements ScheduleTask { long checkPeriod = TimeUnit.MINUTES.toMillis(CHECK_PERIOD_MINUTES); Map events = new HashMap<>(); - for (Device device : deviceManager.getAllDevices()) { - if (device.getLastUpdate() != null && checkDevice(device, currentTime, checkPeriod)) { - Event event = new Event(Event.TYPE_DEVICE_INACTIVE, device.getId()); - event.set(ATTRIBUTE_LAST_UPDATE, device.getLastUpdate().getTime()); - events.put(event, null); + + try { + for (Device device : storage.getObjects(Device.class, new Request(new Columns.All()))) { + if (device.getLastUpdate() != null && checkDevice(device, currentTime, checkPeriod)) { + Event event = new Event(Event.TYPE_DEVICE_INACTIVE, device.getId()); + event.set(ATTRIBUTE_LAST_UPDATE, device.getLastUpdate().getTime()); + events.put(event, null); + } } + } catch (StorageException e) { + LOGGER.warn("Get devices error", e); } notificationManager.updateEvents(events); diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 38d82e848..cead771c9 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -20,7 +20,6 @@ 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.Main; import org.traccar.Protocol; import org.traccar.config.Config; @@ -63,6 +62,8 @@ public class ConnectionManager { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Map deviceStates = new ConcurrentHashMap<>(); + private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -256,7 +257,9 @@ public class ConnectionManager { } try { - Context.getDeviceManager().updateDeviceStatus(device); + storage.updateObject(device, new Request( + new Columns.Include("lastUpdate"), + new Condition.Equals("id", "id"))); } catch (StorageException e) { LOGGER.warn("Update device status error", e); } @@ -264,8 +267,16 @@ public class ConnectionManager { updateDevice(device); } + public DeviceState getDeviceState(long deviceId) { + return deviceStates.computeIfAbsent(deviceId, x -> new DeviceState()); + } + + public void setDeviceState(long deviceId, DeviceState deviceState) { + deviceStates.put(deviceId, deviceState); + } + public Map updateDeviceState(long deviceId) { - DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + DeviceState deviceState = getDeviceState(deviceId); Map result = new HashMap<>(); Map event = Main.getInjector() diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index c7f2a2cc6..707d9d211 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -79,7 +79,7 @@ public class ReportUtilsTest extends BaseTest { public void testCalculateSpentFuel() { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), mock(TripsConfig.class), mock(VelocityEngine.class), null); + mock(TripsConfig.class), mock(VelocityEngine.class), null); Position startPosition = new Position(); Position endPosition = new Position(); assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); @@ -104,7 +104,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -159,7 +159,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -230,7 +230,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -281,7 +281,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -310,7 +310,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -339,7 +339,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -368,7 +368,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -393,7 +393,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); -- cgit v1.2.3 From c79c71a734da5cb4c84dd660744e58675b1d6fb7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:23:16 -0700 Subject: Remove device manager --- src/main/java/org/traccar/Context.java | 20 --- src/main/java/org/traccar/MainModule.java | 6 - .../java/org/traccar/api/BaseObjectResource.java | 36 +---- .../org/traccar/database/BaseObjectManager.java | 174 --------------------- .../java/org/traccar/database/DeviceManager.java | 71 --------- .../org/traccar/database/SimpleObjectManager.java | 27 ---- .../java/org/traccar/reports/ReportUtilsTest.java | 1 - 7 files changed, 5 insertions(+), 330 deletions(-) delete mode 100644 src/main/java/org/traccar/database/BaseObjectManager.java delete mode 100644 src/main/java/org/traccar/database/DeviceManager.java delete mode 100644 src/main/java/org/traccar/database/SimpleObjectManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index c89d39f4c..583ee460b 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -16,12 +16,7 @@ package org.traccar; import org.traccar.config.Config; -import org.traccar.database.BaseObjectManager; -import org.traccar.database.DataManager; -import org.traccar.database.DeviceManager; import org.traccar.helper.Log; -import org.traccar.model.BaseModel; -import org.traccar.model.Device; public final class Context { @@ -34,12 +29,6 @@ public final class Context { return config; } - private static DeviceManager deviceManager; - - public static DeviceManager getDeviceManager() { - return deviceManager; - } - public static void init(String configFile) throws Exception { try { @@ -51,15 +40,6 @@ public final class Context { throw e; } - deviceManager = new DeviceManager(Main.getInjector().getInstance(DataManager.class)); - - } - - public static BaseObjectManager getManager(Class clazz) { - if (clazz.equals(Device.class)) { - return (BaseObjectManager) deviceManager; - } - return null; } } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index d57ee5d38..439dcd1d9 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,7 +30,6 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; @@ -113,11 +112,6 @@ public class MainModule extends AbstractModule { (ContextResolver) clazz -> Main.getInjector().getInstance(ObjectMapper.class)); } - @Provides - public static DeviceManager provideDeviceManager() { - return Context.getDeviceManager(); - } - @Singleton @Provides public static SmsManager provideSmsManager(Config config, Client client) { diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index abfed9682..35ff04bf3 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -16,11 +16,8 @@ */ package org.traccar.api; -import org.traccar.Context; -import org.traccar.database.BaseObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; -import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; @@ -67,15 +64,8 @@ public abstract class BaseObjectResource extends BaseResour public Response add(T entity) throws StorageException { permissionsService.checkEdit(getUserId(), entity, true); - BaseObjectManager manager = Context.getManager(baseClass); - if (manager != null) { - manager.addItem(entity); - } else { - entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); - } - + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); - storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); @@ -100,16 +90,10 @@ public abstract class BaseObjectResource extends BaseResour } } - BaseObjectManager manager = Context.getManager(baseClass); - if (manager != null) { - manager.updateItem(entity); - } else { - storage.updateObject(entity, new Request( - new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); - } + storage.updateObject(entity, new Request( + new Columns.Exclude("id"), + new Condition.Equals("id", "id"))); cacheManager.updateOrInvalidate(entity); - LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); @@ -121,21 +105,11 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), baseClass, false); permissionsService.checkPermission(baseClass, getUserId(), id); - BaseObjectManager manager = Context.getManager(baseClass); - if (manager != null) { - manager.removeItem(id); - } else { - storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); - } + storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); cacheManager.invalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); - if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { - if (baseClass.equals(Group.class)) { - Context.getDeviceManager().updateDeviceCache(true); - } - } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/BaseObjectManager.java b/src/main/java/org/traccar/database/BaseObjectManager.java deleted file mode 100644 index c94053985..000000000 --- a/src/main/java/org/traccar/database/BaseObjectManager.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.database; - -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.BaseModel; -import org.traccar.storage.StorageException; - -public class BaseObjectManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(BaseObjectManager.class); - - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final DataManager dataManager; - - private final Class baseClass; - private Map items; - - protected BaseObjectManager(DataManager dataManager, Class baseClass) { - this.dataManager = dataManager; - this.baseClass = baseClass; - refreshItems(); - } - - protected final void readLock() { - lock.readLock().lock(); - } - - protected final void readUnlock() { - lock.readLock().unlock(); - } - - protected final void writeLock() { - lock.writeLock().lock(); - } - - protected final void writeUnlock() { - lock.writeLock().unlock(); - } - - protected final DataManager getDataManager() { - return dataManager; - } - - public T getById(long itemId) { - try { - readLock(); - return items.get(itemId); - } finally { - readUnlock(); - } - } - - public void refreshItems() { - if (dataManager != null) { - try { - writeLock(); - Collection databaseItems = dataManager.getObjects(baseClass); - if (items == null) { - items = new ConcurrentHashMap<>(databaseItems.size()); - } - Set databaseItemIds = new HashSet<>(); - for (T item : databaseItems) { - databaseItemIds.add(item.getId()); - if (items.containsKey(item.getId())) { - updateCachedItem(item); - } else { - addNewItem(item); - } - } - for (Long cachedItemId : items.keySet()) { - if (!databaseItemIds.contains(cachedItemId)) { - removeCachedItem(cachedItemId); - } - } - } catch (StorageException error) { - LOGGER.warn("Error refreshing items", error); - } finally { - writeUnlock(); - } - } - } - - protected void addNewItem(T item) { - try { - writeLock(); - items.put(item.getId(), item); - } finally { - writeUnlock(); - } - } - - public void addItem(T item) throws StorageException { - dataManager.addObject(item); - addNewItem(item); - } - - protected void updateCachedItem(T item) { - try { - writeLock(); - items.put(item.getId(), item); - } finally { - writeUnlock(); - } - } - - public void updateItem(T item) throws StorageException { - dataManager.updateObject(item); - updateCachedItem(item); - } - - protected void removeCachedItem(long itemId) { - try { - writeLock(); - items.remove(itemId); - } finally { - writeUnlock(); - } - } - - public void removeItem(long itemId) throws StorageException { - BaseModel item = getById(itemId); - if (item != null) { - dataManager.removeObject(baseClass, itemId); - removeCachedItem(itemId); - } - } - - public final Collection getItems(Set itemIds) { - Collection result = new LinkedList<>(); - for (long itemId : itemIds) { - T item = getById(itemId); - if (item != null) { - result.add(item); - } - } - return result; - } - - public Set getAllItems() { - try { - readLock(); - return items.keySet(); - } finally { - readUnlock(); - } - } - -} diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java deleted file mode 100644 index 7a472c2d4..000000000 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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. - * 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.database; - -import org.traccar.model.Device; - -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; - -public class DeviceManager extends BaseObjectManager { - - private final AtomicLong devicesLastUpdate = new AtomicLong(); - - public DeviceManager(DataManager dataManager) { - super(dataManager, Device.class); - } - - public void updateDeviceCache(boolean force) { - long lastUpdate = devicesLastUpdate.get(); - if ((force || System.currentTimeMillis() - lastUpdate > 300000L) - && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { - refreshItems(); - } - } - - @Override - public Set getAllItems() { - Set result = super.getAllItems(); - if (result.isEmpty()) { - updateDeviceCache(true); - result = super.getAllItems(); - } - return result; - } - - @Override - protected void updateCachedItem(Device device) { - Device cachedDevice = getById(device.getId()); - cachedDevice.setName(device.getName()); - cachedDevice.setGroupId(device.getGroupId()); - cachedDevice.setCategory(device.getCategory()); - cachedDevice.setContact(device.getContact()); - cachedDevice.setPhone(device.getPhone()); - cachedDevice.setModel(device.getModel()); - cachedDevice.setDisabled(device.getDisabled()); - cachedDevice.setAttributes(device.getAttributes()); - cachedDevice.setUniqueId(device.getUniqueId()); - } - - @Override - protected void removeCachedItem(long deviceId) { - Device cachedDevice = getById(deviceId); - if (cachedDevice != null) { - super.removeCachedItem(deviceId); - } - } - -} diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java deleted file mode 100644 index 8bb22b8a8..000000000 --- a/src/main/java/org/traccar/database/SimpleObjectManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.database; - -import org.traccar.model.BaseModel; - -public abstract class SimpleObjectManager extends BaseObjectManager { - - protected SimpleObjectManager(DataManager dataManager, Class baseClass) { - super(dataManager, baseClass); - } - -} diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 707d9d211..dfb2ef05c 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -6,7 +6,6 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; -import org.traccar.database.DeviceManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; -- cgit v1.2.3 From 6fe1f8ed83680204fe7ec50382588dbe82fec1ba Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:26:15 -0700 Subject: Remove data manager --- .../java/org/traccar/database/DataManager.java | 60 ---------------------- .../org/traccar/database/StatisticsManager.java | 11 ++-- .../org/traccar/handler/DefaultDataHandler.java | 12 +++-- 3 files changed, 14 insertions(+), 69 deletions(-) delete mode 100644 src/main/java/org/traccar/database/DataManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java deleted file mode 100644 index 398c63892..000000000 --- a/src/main/java/org/traccar/database/DataManager.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012 - 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.database; - -import org.traccar.model.BaseModel; -import org.traccar.model.Server; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.inject.Inject; -import java.util.Collection; - -public class DataManager { - - private final Storage storage; - - @Inject - public DataManager(Storage storage) { - this.storage = storage; - } - - public Server getServer() throws StorageException { - return storage.getObject(Server.class, new Request(new Columns.All())); - } - - public Collection getObjects(Class clazz) throws StorageException { - return storage.getObjects(clazz, new Request(new Columns.All())); - } - - public void addObject(BaseModel entity) throws StorageException { - entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); - } - - public void updateObject(BaseModel entity) throws StorageException { - storage.updateObject(entity, new Request( - new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); - } - - public void removeObject(Class clazz, long entityId) throws StorageException { - storage.removeObject(clazz, new Request(new Condition.Equals("id", "id", entityId))); - } - -} diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index d5a179cbe..e0995dabc 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -23,7 +23,10 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DateUtil; import org.traccar.model.Statistics; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; @@ -46,7 +49,7 @@ public class StatisticsManager { private static final int SPLIT_MODE = Calendar.DAY_OF_MONTH; private final Config config; - private final DataManager dataManager; + private final Storage storage; private final Client client; private final ObjectMapper objectMapper; @@ -64,9 +67,9 @@ public class StatisticsManager { private int geolocationRequests; @Inject - public StatisticsManager(Config config, DataManager dataManager, Client client, ObjectMapper objectMapper) { + public StatisticsManager(Config config, Storage storage, Client client, ObjectMapper objectMapper) { this.config = config; - this.dataManager = dataManager; + this.storage = storage; this.client = client; this.objectMapper = objectMapper; } @@ -107,7 +110,7 @@ public class StatisticsManager { } try { - dataManager.addObject(statistics); + storage.addObject(statistics, new Request(new Columns.Exclude("id"))); } catch (StorageException e) { LOGGER.warn("Error saving statistics", e); } diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java index c2adfd799..f6a20628b 100644 --- a/src/main/java/org/traccar/handler/DefaultDataHandler.java +++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java @@ -19,8 +19,10 @@ import io.netty.channel.ChannelHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; -import org.traccar.database.DataManager; import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.inject.Inject; @@ -29,18 +31,18 @@ public class DefaultDataHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDataHandler.class); - private final DataManager dataManager; + private final Storage storage; @Inject - public DefaultDataHandler(DataManager dataManager) { - this.dataManager = dataManager; + public DefaultDataHandler(Storage storage) { + this.storage = storage; } @Override protected Position handlePosition(Position position) { try { - dataManager.addObject(position); + position.setId(storage.addObject(position, new Request(new Columns.Exclude("id")))); } catch (Exception error) { LOGGER.warn("Failed to store position", error); } -- cgit v1.2.3 From e65bfeab8dafb02c21b360b4970d5d94013f53f6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:36:32 -0700 Subject: Finally remove context --- src/main/java/org/traccar/Context.java | 45 ---------------------- src/main/java/org/traccar/Main.java | 3 +- src/main/java/org/traccar/MainModule.java | 22 ++++++++++- src/main/java/org/traccar/TrackerClient.java | 2 +- src/main/java/org/traccar/TrackerServer.java | 2 +- .../java/org/traccar/api/AsyncSocketServlet.java | 9 +++-- .../java/org/traccar/api/CorsResponseFilter.java | 14 +++++-- 7 files changed, 39 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/org/traccar/Context.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java deleted file mode 100644 index 583ee460b..000000000 --- a/src/main/java/org/traccar/Context.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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; - -import org.traccar.config.Config; -import org.traccar.helper.Log; - -public final class Context { - - private Context() { - } - - private static Config config; - - public static Config getConfig() { - return config; - } - - public static void init(String configFile) throws Exception { - - try { - config = new Config(configFile); - Log.setupLogger(config); - } catch (Exception e) { - config = new Config(); - Log.setupDefaultLogger(); - throw e; - } - - } - -} diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index bf69b565d..6a968ac7e 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -115,8 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new WebModule()); - Context.init(configFile); + injector = Guice.createInjector(new MainModule(configFile), new DatabaseModule(), new WebModule()); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 439dcd1d9..7dcc91f32 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -22,6 +22,8 @@ import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; +import com.google.inject.name.Named; +import com.google.inject.name.Names; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.apache.velocity.app.VelocityEngine; @@ -59,6 +61,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; @@ -83,8 +86,15 @@ import java.util.Properties; public class MainModule extends AbstractModule { + private final String configFile; + + public MainModule(String configFile) { + this.configFile = configFile; + } + @Override protected void configure() { + bindConstant().annotatedWith(Names.named("configFile")).to(configFile); bind(Storage.class).to(DatabaseStorage.class); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } @@ -101,9 +111,17 @@ public class MainModule extends AbstractModule { return objectMapper; } + @Singleton @Provides - public static Config provideConfig() { - return Context.getConfig(); + public static Config provideConfig(@Named("configFile") String configFile) throws Exception { + try { + Config config = new Config(configFile); + Log.setupLogger(config); + return config; + } catch (Exception e) { + Log.setupDefaultLogger(); + throw e; + } } @Provides diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index 5a3c38212..2e8a73677 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -54,7 +54,7 @@ public abstract class TrackerClient implements TrackerConnector { } public TrackerClient(String protocol) { - Config config = Context.getConfig(); + Config config = Main.getInjector().getInstance(Config.class); secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); interval = config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index dd83ca6b0..ccf3cd640 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -58,7 +58,7 @@ public abstract class TrackerServer implements TrackerConnector { public TrackerServer(boolean datagram, String protocol) { this.datagram = datagram; - Config config = Context.getConfig(); + Config config = Main.getInjector().getInstance(Config.class); secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 7d9fdf0ed..40e1551a1 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -18,8 +18,8 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; -import org.traccar.Context; import org.traccar.api.resource.SessionResource; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; import org.traccar.storage.Storage; @@ -32,12 +32,15 @@ import java.time.Duration; @Singleton public class AsyncSocketServlet extends JettyWebSocketServlet { + private final Config config; private final ObjectMapper objectMapper; private final ConnectionManager connectionManager; private final Storage storage; @Inject - public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage) { + public AsyncSocketServlet( + Config config, ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage) { + this.config = config; this.objectMapper = objectMapper; this.connectionManager = connectionManager; this.storage = storage; @@ -45,7 +48,7 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { @Override public void configure(JettyWebSocketServletFactory factory) { - factory.setIdleTimeout(Duration.ofMillis(Context.getConfig().getLong(Keys.WEB_TIMEOUT))); + factory.setIdleTimeout(Duration.ofMillis(config.getLong(Keys.WEB_TIMEOUT))); factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); diff --git a/src/main/java/org/traccar/api/CorsResponseFilter.java b/src/main/java/org/traccar/api/CorsResponseFilter.java index 91aea5718..5375e207f 100644 --- a/src/main/java/org/traccar/api/CorsResponseFilter.java +++ b/src/main/java/org/traccar/api/CorsResponseFilter.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. @@ -16,9 +16,10 @@ package org.traccar.api; import io.netty.handler.codec.http.HttpHeaderNames; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; +import javax.inject.Inject; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; @@ -26,6 +27,13 @@ import java.io.IOException; public class CorsResponseFilter implements ContainerResponseFilter { + private final String allowed; + + @Inject + public CorsResponseFilter(Config config) { + allowed = config.getString(Keys.WEB_ORIGIN); + } + private static final String ORIGIN_ALL = "*"; private static final String HEADERS_ALL = "origin, content-type, accept, authorization"; private static final String METHODS_ALL = "GET, POST, PUT, DELETE, OPTIONS"; @@ -46,8 +54,6 @@ public class CorsResponseFilter implements ContainerResponseFilter { if (!response.getHeaders().containsKey(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString())) { String origin = request.getHeaderString(HttpHeaderNames.ORIGIN.toString()); - String allowed = Context.getConfig().getString(Keys.WEB_ORIGIN); - if (origin == null) { response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString(), ORIGIN_ALL); } else if (allowed == null || allowed.equals(ORIGIN_ALL) || allowed.contains(origin)) { -- cgit v1.2.3 From 4d59dd0973479bca3d51cf3bba6b0769a0d671c3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:47:56 -0700 Subject: Fix config injection --- src/main/java/org/traccar/MainModule.java | 16 +--------------- src/main/java/org/traccar/config/Config.java | 14 +++++++++++++- 2 files changed, 14 insertions(+), 16 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 7dcc91f32..39d5a656a 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -22,7 +22,6 @@ import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; -import com.google.inject.name.Named; import com.google.inject.name.Names; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; @@ -61,7 +60,6 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; @@ -95,6 +93,7 @@ public class MainModule extends AbstractModule { @Override protected void configure() { bindConstant().annotatedWith(Names.named("configFile")).to(configFile); + bind(Config.class).asEagerSingleton(); bind(Storage.class).to(DatabaseStorage.class); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } @@ -111,19 +110,6 @@ public class MainModule extends AbstractModule { return objectMapper; } - @Singleton - @Provides - public static Config provideConfig(@Named("configFile") String configFile) throws Exception { - try { - Config config = new Config(configFile); - Log.setupLogger(config); - return config; - } catch (Exception e) { - Log.setupDefaultLogger(); - throw e; - } - } - @Provides public static Client provideClient() { return ClientBuilder.newClient().register( diff --git a/src/main/java/org/traccar/config/Config.java b/src/main/java/org/traccar/config/Config.java index 815a6e86a..5f95c16d9 100644 --- a/src/main/java/org/traccar/config/Config.java +++ b/src/main/java/org/traccar/config/Config.java @@ -16,13 +16,18 @@ package org.traccar.config; import com.google.common.annotations.VisibleForTesting; +import com.google.inject.name.Named; +import org.traccar.helper.Log; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.InvalidPropertiesFormatException; import java.util.Properties; +@Singleton public class Config { private final Properties properties = new Properties(); @@ -32,7 +37,8 @@ public class Config { public Config() { } - public Config(String file) throws IOException { + @Inject + public Config(@Named("configFile") String file) throws IOException { try { Properties mainProperties = new Properties(); try (InputStream inputStream = new FileInputStream(file)) { @@ -50,8 +56,14 @@ public class Config { useEnvironmentVariables = Boolean.parseBoolean(System.getenv("CONFIG_USE_ENVIRONMENT_VARIABLES")) || Boolean.parseBoolean(properties.getProperty("config.useEnvironmentVariables")); + + Log.setupLogger(this); } catch (InvalidPropertiesFormatException e) { + Log.setupDefaultLogger(); throw new RuntimeException("Configuration file is not a valid XML document", e); + } catch (Exception e) { + Log.setupDefaultLogger(); + throw e; } } -- cgit v1.2.3 From 8ed8f8051b735a6f7c9480601e27339dbe8dab01 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:52:08 -0700 Subject: Fix config defaults --- src/main/java/org/traccar/config/Keys.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6eb61607e..a03e47022 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -306,14 +306,16 @@ public final class Keys { */ public static final ConfigKey EVENT_FUEL_DROP_THRESHOLD = new DoubleConfigKey( "fuelDropThreshold", - List.of(KeyType.SERVER, KeyType.DEVICE)); + List.of(KeyType.SERVER, KeyType.DEVICE), + 0.0); /** * Speed limit value in knots. */ public static final ConfigKey EVENT_OVERSPEED_LIMIT = new DoubleConfigKey( "speedLimit", - List.of(KeyType.SERVER, KeyType.DEVICE)); + List.of(KeyType.SERVER, KeyType.DEVICE), + 0.0); /** * If true, the event is generated once at the beginning of overspeeding period. -- cgit v1.2.3 From ed64af90036d5e29b1e5fdf68df68c5c126beff7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 14:12:05 -0700 Subject: Fix geocoder injection --- src/main/java/org/traccar/MainModule.java | 56 +++++++++++++++------- src/main/java/org/traccar/geocoder/Geocoder.java | 4 ++ .../java/org/traccar/geocoder/JsonGeocoder.java | 13 +++-- 3 files changed, 51 insertions(+), 22 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 39d5a656a..3120118fc 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -146,7 +146,7 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static Geocoder provideGeocoder(Config config, Client client) { + public static Geocoder provideGeocoder(Config config, Client client, StatisticsManager statisticsManager) { if (config.getBoolean(Keys.GEOCODER_ENABLE)) { String type = config.getString(Keys.GEOCODER_TYPE, "google"); String url = config.getString(Keys.GEOCODER_URL); @@ -157,42 +157,62 @@ public class MainModule extends AbstractModule { AddressFormat addressFormat = formatString != null ? new AddressFormat(formatString) : new AddressFormat(); int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); + Geocoder geocoder; switch (type) { case "nominatim": - return new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); + geocoder = new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); + break; case "gisgraphy": - return new GisgraphyGeocoder(client, url, cacheSize, addressFormat); + geocoder = new GisgraphyGeocoder(client, url, cacheSize, addressFormat); + break; case "mapquest": - return new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); + break; case "opencage": - return new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); + geocoder = new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); + break; case "bingmaps": - return new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); + break; case "factual": - return new FactualGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new FactualGeocoder(client, url, key, cacheSize, addressFormat); + break; case "geocodefarm": - return new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); + geocoder = new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); + break; case "geocodexyz": - return new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); + geocoder = new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); + break; case "ban": - return new BanGeocoder(client, cacheSize, addressFormat); + geocoder = new BanGeocoder(client, cacheSize, addressFormat); + break; case "here": - return new HereGeocoder(client, url, id, key, language, cacheSize, addressFormat); + geocoder = new HereGeocoder(client, url, id, key, language, cacheSize, addressFormat); + break; case "mapmyindia": - return new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); + break; case "tomtom": - return new TomTomGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new TomTomGeocoder(client, url, key, cacheSize, addressFormat); + break; case "positionstack": - return new PositionStackGeocoder(client, key, cacheSize, addressFormat); + geocoder = new PositionStackGeocoder(client, key, cacheSize, addressFormat); + break; case "mapbox": - return new MapboxGeocoder(client, key, cacheSize, addressFormat); + geocoder = new MapboxGeocoder(client, key, cacheSize, addressFormat); + break; case "maptiler": - return new MapTilerGeocoder(client, key, cacheSize, addressFormat); + geocoder = new MapTilerGeocoder(client, key, cacheSize, addressFormat); + break; case "geoapify": - return new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); + geocoder = new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); + break; default: - return new GoogleGeocoder(client, key, language, cacheSize, addressFormat); + geocoder = new GoogleGeocoder(client, key, language, cacheSize, addressFormat); + break; } + geocoder.setStatisticsManager(statisticsManager); + return geocoder; } return null; } diff --git a/src/main/java/org/traccar/geocoder/Geocoder.java b/src/main/java/org/traccar/geocoder/Geocoder.java index 587a27520..f4abe871a 100644 --- a/src/main/java/org/traccar/geocoder/Geocoder.java +++ b/src/main/java/org/traccar/geocoder/Geocoder.java @@ -15,6 +15,8 @@ */ package org.traccar.geocoder; +import org.traccar.database.StatisticsManager; + public interface Geocoder { interface ReverseGeocoderCallback { @@ -27,4 +29,6 @@ public interface Geocoder { String getAddress(double latitude, double longitude, ReverseGeocoderCallback callback); + void setStatisticsManager(StatisticsManager statisticsManager); + } diff --git a/src/main/java/org/traccar/geocoder/JsonGeocoder.java b/src/main/java/org/traccar/geocoder/JsonGeocoder.java index 0262de18c..6105e8cfd 100644 --- a/src/main/java/org/traccar/geocoder/JsonGeocoder.java +++ b/src/main/java/org/traccar/geocoder/JsonGeocoder.java @@ -17,7 +17,6 @@ package org.traccar.geocoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.database.StatisticsManager; import javax.json.JsonObject; @@ -36,6 +35,7 @@ public abstract class JsonGeocoder implements Geocoder { private final Client client; private final String url; private final AddressFormat addressFormat; + private StatisticsManager statisticsManager; private Map, String> cache; @@ -44,7 +44,7 @@ public abstract class JsonGeocoder implements Geocoder { this.url = url; this.addressFormat = addressFormat; if (cacheSize > 0) { - this.cache = Collections.synchronizedMap(new LinkedHashMap, String>() { + this.cache = Collections.synchronizedMap(new LinkedHashMap<>() { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > cacheSize; @@ -53,6 +53,11 @@ public abstract class JsonGeocoder implements Geocoder { } } + @Override + public void setStatisticsManager(StatisticsManager statisticsManager) { + this.statisticsManager = statisticsManager; + } + protected String readValue(JsonObject object, String key) { if (object.containsKey(key) && !object.isNull(key)) { return object.getString(key); @@ -98,8 +103,8 @@ public abstract class JsonGeocoder implements Geocoder { } } - if (Main.getInjector() != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); + if (statisticsManager != null) { + statisticsManager.registerGeocoderRequest(); } var request = client.target(String.format(url, latitude, longitude)).request(); -- cgit v1.2.3 From 367c6266918a9f21ec6a9eabd091b00016c1d1bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 14:27:24 -0700 Subject: Inject all protocols --- src/main/java/org/traccar/ServerManager.java | 3 +-- src/main/java/org/traccar/TrackerClient.java | 4 +--- src/main/java/org/traccar/TrackerServer.java | 11 ++--------- src/main/java/org/traccar/protocol/AdmProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AisProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AlematicsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AnytrekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ApelProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AplicomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AppelloProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AquilaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Ardi01Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArknavProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArknavX8Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArmoliProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArnaviProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AstraProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/At2000Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AtrackProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/AuroProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AustinNbProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AutoFonProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AutoGradeProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AutoTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AvemaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Avl301Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/B2316Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BceProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BlackKiteProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BlueProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BoxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/C2stekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CalAmpProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CarTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CarcellProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CarscopProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CastelProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/CautelaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CellocatorProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/CguardProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CityeasyProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ContinentalProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CradlepointProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DingtekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DishaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DmtHttpProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DmtProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DolphinProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Dsf22Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/DualcamProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DwayProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EasyTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EelinkProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/EgtsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EnforaProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/EnnfuProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EnvotechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EsealProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EskyProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/ExtremTracProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FifotrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlespiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlexApiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlexCommProtocol.java | 7 +++++-- .../java/org/traccar/protocol/FlexibleReportProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlextrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FoxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FreedomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FreematicsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FutureWayProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GalileoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GatorProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GenxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gl100Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Gl200Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GlobalSatProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GlobalstarProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GnxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GoSafeProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GotopProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gps056Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gps103Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GpsGateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GpsMarkerProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GpsmtaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GranitProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gs100Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gt02Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gt06Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gt30Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/H02Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/HaicomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HomtecsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HoopoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HuaShengProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HuabaoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HunterProProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/IdplProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/IntellitracProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/IotmProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ItsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Ivt401Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/JidoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/JpKorjarProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Jt600Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/KenjiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/KhdProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/L100Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/LacakProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/LaipacProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/LeafSpyProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/M2cProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/M2mProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MaestroProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ManPowerProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Mavlink2Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MegastekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MeiligaoProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/MeitrackProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/MictrackProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/MilesmateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MiniFinderProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Minifinder2Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MobilogixProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MoovboxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MotorProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Mta6Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MtxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MxtProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavigilProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavisProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavisetProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavtelecomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NeosProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NetProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NiotProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NoranProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NvsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NyitechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ObdDongleProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OigoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OkoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OmnicommProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OpenGtsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OrbcommProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OrionProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OsmAndProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OutsafeProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OwnTracksProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PacificTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PathAwayProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PiligrimProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PluginProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PolteProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PortmanProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PretraceProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PricolProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/ProgressProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PstProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Pt215Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Pt3000Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Pt502Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Pt60Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/R12wProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RadarProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RaveonProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RecodaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RetranslatorProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RitiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RoboTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RstProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RuptelaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/S168Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SabertekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SanavProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/SanulProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SatsolProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SigfoxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SiwiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SkypatrolProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SmartSoleProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SmokeyProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SolarPoweredProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SpotProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StarLinkProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StarcomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StartekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StbProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Stl060Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SuntechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SupermateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SviasProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SwiftechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/T55Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/T57Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/T800xProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TaipProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TechTltProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TechtoCruzProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TelemaxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TelicProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TeltonikaProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TeraTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ThinkPowerProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ThinkRaceProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tk102Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tk103Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Tlt2hProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TlvProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TmgProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TopflytechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TopinProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TotemProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tr20Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Tr900Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TrackboxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TrakMateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TramigoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TrvProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tt8850Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TytanProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TzoneProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/UlbotechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/UproProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/UuxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/V680Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/VisiontekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/VnetProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Vt200Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/VtfmsProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/WatchProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/WialonProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/WliProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/WondexProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/WristbandProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Xexun2Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/XexunProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/XirgoProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Xrb28Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Xt013Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Xt2400Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/YwtProtocol.java | 7 +++++-- 244 files changed, 1242 insertions(+), 529 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 99fb9a494..8d6e615dc 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -46,8 +46,7 @@ public class ServerManager implements LifecycleObject { Injector injector, Config config) throws IOException, URISyntaxException, ReflectiveOperationException { for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { - BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); - injector.injectMembers(protocol); + BaseProtocol protocol = (BaseProtocol) injector.getInstance(protocolClass); connectorList.addAll(protocol.getConnectorList()); protocolList.put(protocol.getName(), protocol); } diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index 2e8a73677..2d6b227da 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -53,9 +53,7 @@ public abstract class TrackerClient implements TrackerConnector { return secure; } - public TrackerClient(String protocol) { - Config config = Main.getInjector().getInstance(Config.class); - + public TrackerClient(Config config, String protocol) { secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); interval = config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index ccf3cd640..0e0837cfb 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -55,11 +55,7 @@ public abstract class TrackerServer implements TrackerConnector { return secure; } - public TrackerServer(boolean datagram, String protocol) { - this.datagram = datagram; - - Config config = Main.getInjector().getInstance(Config.class); - + public TrackerServer(Config config, String protocol, boolean datagram) { secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); @@ -83,20 +79,17 @@ public abstract class TrackerServer implements TrackerConnector { } }; + this.datagram = datagram; if (datagram) { - bootstrap = new Bootstrap() .group(EventLoopGroupFactory.getWorkerGroup()) .channel(NioDatagramChannel.class) .handler(pipelineFactory); - } else { - bootstrap = new ServerBootstrap() .group(EventLoopGroupFactory.getBossGroup(), EventLoopGroupFactory.getWorkerGroup()) .channel(NioServerSocketChannel.class) .childHandler(pipelineFactory); - } } diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java index 8c5e2de0d..bab1d2339 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocol.java +++ b/src/main/java/org/traccar/protocol/AdmProtocol.java @@ -22,13 +22,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class AdmProtocol extends BaseProtocol { - public AdmProtocol() { + @Inject + public AdmProtocol(Config config) { setSupportedDataCommands( Command.TYPE_GET_DEVICE_STATUS, Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AdmFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AisProtocol.java b/src/main/java/org/traccar/protocol/AisProtocol.java index 5697d7f3f..bc975c277 100644 --- a/src/main/java/org/traccar/protocol/AisProtocol.java +++ b/src/main/java/org/traccar/protocol/AisProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AisProtocol extends BaseProtocol { - public AisProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AisProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocol.java b/src/main/java/org/traccar/protocol/AlematicsProtocol.java index 1e68949ae..b85b44382 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AlematicsProtocol extends BaseProtocol { - public AlematicsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AlematicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AlematicsFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocol.java b/src/main/java/org/traccar/protocol/AnytrekProtocol.java index 8c020e64e..b0e974c69 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocol.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class AnytrekProtocol extends BaseProtocol { - public AnytrekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AnytrekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 2, 0, true)); diff --git a/src/main/java/org/traccar/protocol/ApelProtocol.java b/src/main/java/org/traccar/protocol/ApelProtocol.java index 0c0d6279e..f1d6e659c 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocol.java +++ b/src/main/java/org/traccar/protocol/ApelProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class ApelProtocol extends BaseProtocol { - public ApelProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ApelProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/AplicomProtocol.java b/src/main/java/org/traccar/protocol/AplicomProtocol.java index 21556bd69..47bb780cb 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocol.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AplicomProtocol extends BaseProtocol { - public AplicomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AplicomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AplicomFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AppelloProtocol.java b/src/main/java/org/traccar/protocol/AppelloProtocol.java index 919c8ab62..25b2bf3b8 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocol.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AppelloProtocol extends BaseProtocol { - public AppelloProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AppelloProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/AquilaProtocol.java b/src/main/java/org/traccar/protocol/AquilaProtocol.java index 72161ccec..6080df33d 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocol.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AquilaProtocol extends BaseProtocol { - public AquilaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AquilaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Ardi01Protocol.java b/src/main/java/org/traccar/protocol/Ardi01Protocol.java index ba9dc9dfa..b33c2817f 100644 --- a/src/main/java/org/traccar/protocol/Ardi01Protocol.java +++ b/src/main/java/org/traccar/protocol/Ardi01Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Ardi01Protocol extends BaseProtocol { - public Ardi01Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Ardi01Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index 76db3781c..ed38f26d7 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArknavProtocol extends BaseProtocol { - public ArknavProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArknavProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); diff --git a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java index 55d2c58f9..39c6e8009 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java +++ b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArknavX8Protocol extends BaseProtocol { - public ArknavX8Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArknavX8Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 70e70c89b..32fba3b52 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArmoliProtocol extends BaseProtocol { - public ArmoliProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArmoliProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";;", ";\r", ";")); diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocol.java b/src/main/java/org/traccar/protocol/ArnaviProtocol.java index 18af4e9be..091d5c06f 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocol.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArnaviProtocol extends BaseProtocol { - public ArnaviProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArnaviProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ArnaviFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AstraProtocol.java b/src/main/java/org/traccar/protocol/AstraProtocol.java index c79c7f6fc..021a81e07 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocol.java +++ b/src/main/java/org/traccar/protocol/AstraProtocol.java @@ -21,17 +21,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AstraProtocol extends BaseProtocol { - public AstraProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AstraProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/At2000Protocol.java b/src/main/java/org/traccar/protocol/At2000Protocol.java index 44bb11b94..25e9be86f 100644 --- a/src/main/java/org/traccar/protocol/At2000Protocol.java +++ b/src/main/java/org/traccar/protocol/At2000Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class At2000Protocol extends BaseProtocol { - public At2000Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public At2000Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new At2000FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java index 65cd5194e..21eb09696 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class AtrackProtocol extends BaseProtocol { - public AtrackProtocol() { + @Inject + public AtrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackFrameDecoder()); @@ -34,7 +37,7 @@ public class AtrackProtocol extends BaseProtocol { pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AuroProtocol.java b/src/main/java/org/traccar/protocol/AuroProtocol.java index f05b3f71c..d37884c8b 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocol.java +++ b/src/main/java/org/traccar/protocol/AuroProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AuroProtocol extends BaseProtocol { - public AuroProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AuroProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocol.java b/src/main/java/org/traccar/protocol/AustinNbProtocol.java index 18a1c6c6a..6a68467e2 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocol.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AustinNbProtocol extends BaseProtocol { - public AustinNbProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public AustinNbProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocol.java b/src/main/java/org/traccar/protocol/AutoFonProtocol.java index 36d384c94..0566b1da6 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AutoFonProtocol extends BaseProtocol { - public AutoFonProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoFonProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AutoFonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java index c9d997163..bc80e473a 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AutoGradeProtocol extends BaseProtocol { - public AutoGradeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoGradeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java index 99a59fad7..80255d3e9 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class AutoTrackProtocol extends BaseProtocol { - public AutoTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 5, 2, 2, 0, true)); diff --git a/src/main/java/org/traccar/protocol/AvemaProtocol.java b/src/main/java/org/traccar/protocol/AvemaProtocol.java index 69d2cbfa7..b35a447ff 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocol.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AvemaProtocol extends BaseProtocol { - public AvemaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AvemaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Avl301Protocol.java b/src/main/java/org/traccar/protocol/Avl301Protocol.java index bae4de7d0..c4a0affdc 100644 --- a/src/main/java/org/traccar/protocol/Avl301Protocol.java +++ b/src/main/java/org/traccar/protocol/Avl301Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Avl301Protocol extends BaseProtocol { - public Avl301Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Avl301Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, -3, 0)); diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java index 5b9d297f9..582be0b56 100644 --- a/src/main/java/org/traccar/protocol/B2316Protocol.java +++ b/src/main/java/org/traccar/protocol/B2316Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class B2316Protocol extends BaseProtocol { - public B2316Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public B2316Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java index 2d92894aa..31fb1bd83 100644 --- a/src/main/java/org/traccar/protocol/BceProtocol.java +++ b/src/main/java/org/traccar/protocol/BceProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class BceProtocol extends BaseProtocol { - public BceProtocol() { + @Inject + public BceProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new BceFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java index e464b18d1..3859a9273 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class BlackKiteProtocol extends BaseProtocol { - public BlackKiteProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BlackKiteProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/BlueProtocol.java b/src/main/java/org/traccar/protocol/BlueProtocol.java index 9d42e386e..da195f438 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocol.java +++ b/src/main/java/org/traccar/protocol/BlueProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class BlueProtocol extends BaseProtocol { - public BlueProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BlueProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -2, 0)); diff --git a/src/main/java/org/traccar/protocol/BoxProtocol.java b/src/main/java/org/traccar/protocol/BoxProtocol.java index 72a13c94a..dc6852d50 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocol.java +++ b/src/main/java/org/traccar/protocol/BoxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class BoxProtocol extends BaseProtocol { - public BoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); diff --git a/src/main/java/org/traccar/protocol/C2stekProtocol.java b/src/main/java/org/traccar/protocol/C2stekProtocol.java index da490aedc..5cd8ef4fd 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocol.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class C2stekProtocol extends BaseProtocol { - public C2stekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public C2stekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, false, "$AP")); diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocol.java b/src/main/java/org/traccar/protocol/CalAmpProtocol.java index 056f23d01..d67308cf2 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocol.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CalAmpProtocol extends BaseProtocol { - public CalAmpProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public CalAmpProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CalAmpProtocolDecoder(CalAmpProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocol.java b/src/main/java/org/traccar/protocol/CarTrackProtocol.java index 133fd8036..0538aad72 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CarTrackProtocol extends BaseProtocol { - public CarTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CarTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java index 489b1d1de..832d9bb2d 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocol.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java @@ -24,13 +24,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CarcellProtocol extends BaseProtocol { - public CarcellProtocol() { + @Inject + public CarcellProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); diff --git a/src/main/java/org/traccar/protocol/CarscopProtocol.java b/src/main/java/org/traccar/protocol/CarscopProtocol.java index d4c246c59..a4413af28 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocol.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CarscopProtocol extends BaseProtocol { - public CarscopProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CarscopProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '^')); diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java index ee5432753..9323b1503 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocol.java +++ b/src/main/java/org/traccar/protocol/CastelProtocol.java @@ -23,13 +23,16 @@ import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.ByteOrder; +import javax.inject.Inject; + public class CastelProtocol extends BaseProtocol { - public CastelProtocol() { + @Inject + public CastelProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); @@ -37,7 +40,7 @@ public class CastelProtocol extends BaseProtocol { pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/CautelaProtocol.java b/src/main/java/org/traccar/protocol/CautelaProtocol.java index 13f3770b7..d0ca35ef1 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocol.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CautelaProtocol extends BaseProtocol { - public CautelaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CautelaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java index 6532848ac..3287928c7 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CellocatorProtocol extends BaseProtocol { - public CellocatorProtocol() { + @Inject + public CellocatorProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorFrameDecoder()); @@ -34,7 +37,7 @@ public class CellocatorProtocol extends BaseProtocol { pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/CguardProtocol.java b/src/main/java/org/traccar/protocol/CguardProtocol.java index ad5539fbd..caf0aad42 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocol.java +++ b/src/main/java/org/traccar/protocol/CguardProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CguardProtocol extends BaseProtocol { - public CguardProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CguardProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java index 28337bde9..9656b284b 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java @@ -22,15 +22,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CityeasyProtocol extends BaseProtocol { - public CityeasyProtocol() { + @Inject + public CityeasyProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, Command.TYPE_SET_TIMEZONE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocol.java b/src/main/java/org/traccar/protocol/ContinentalProtocol.java index bbff3bda6..06e93d79d 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocol.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ContinentalProtocol extends BaseProtocol { - public ContinentalProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ContinentalProtocol(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)); diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocol.java b/src/main/java/org/traccar/protocol/CradlepointProtocol.java index 7d2270743..7f201a31d 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocol.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CradlepointProtocol extends BaseProtocol { - public CradlepointProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CradlepointProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/DingtekProtocol.java b/src/main/java/org/traccar/protocol/DingtekProtocol.java index 7864d24df..e9466b7e8 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocol.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DingtekProtocol extends BaseProtocol { - public DingtekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DingtekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DingtekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/DishaProtocol.java b/src/main/java/org/traccar/protocol/DishaProtocol.java index c81c88c7c..f83b8349a 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocol.java +++ b/src/main/java/org/traccar/protocol/DishaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DishaProtocol extends BaseProtocol { - public DishaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DishaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java index 107ec430c..0dab26cda 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DmtHttpProtocol extends BaseProtocol { - public DmtHttpProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DmtHttpProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/DmtProtocol.java b/src/main/java/org/traccar/protocol/DmtProtocol.java index d84099fac..de56c9372 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class DmtProtocol extends BaseProtocol { - public DmtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DmtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); diff --git a/src/main/java/org/traccar/protocol/DolphinProtocol.java b/src/main/java/org/traccar/protocol/DolphinProtocol.java index 1e67de8b2..ed627be78 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocol.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class DolphinProtocol extends BaseProtocol { - public DolphinProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DolphinProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 4096, 20, 4, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/Dsf22Protocol.java b/src/main/java/org/traccar/protocol/Dsf22Protocol.java index fcc7e7d55..06c99b0f9 100644 --- a/src/main/java/org/traccar/protocol/Dsf22Protocol.java +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.java @@ -20,17 +20,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Dsf22Protocol extends BaseProtocol { - public Dsf22Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Dsf22Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22FrameDecoder()); pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java index ba1dc0e4b..363a2c5d9 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DualcamProtocol extends BaseProtocol { - public DualcamProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DualcamProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DualcamFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/DwayProtocol.java b/src/main/java/org/traccar/protocol/DwayProtocol.java index a729d6401..1096c945c 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocol.java +++ b/src/main/java/org/traccar/protocol/DwayProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DwayProtocol extends BaseProtocol { - public DwayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DwayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java index 0c1fec7e8..39aa61580 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java @@ -24,15 +24,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EasyTrackProtocol extends BaseProtocol { - public EasyTrackProtocol() { + @Inject + public EasyTrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#\r\n", "#", "\r\n")); diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java index 654468ea0..35fd4fe65 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocol.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java @@ -22,16 +22,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EelinkProtocol extends BaseProtocol { - public EelinkProtocol() { + @Inject + public EelinkProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); @@ -39,7 +42,7 @@ public class EelinkProtocol extends BaseProtocol { pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, true)); diff --git a/src/main/java/org/traccar/protocol/EgtsProtocol.java b/src/main/java/org/traccar/protocol/EgtsProtocol.java index fb17e41ae..f257271d4 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocol.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EgtsProtocol extends BaseProtocol { - public EgtsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EgtsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EgtsFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java index 5386787ea..ebde56f70 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocol.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java @@ -22,14 +22,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EnforaProtocol extends BaseProtocol { - public EnforaProtocol() { + @Inject + public EnforaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); @@ -37,7 +40,7 @@ public class EnforaProtocol extends BaseProtocol { pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocol.java b/src/main/java/org/traccar/protocol/EnnfuProtocol.java index e72ff29ba..e326481fa 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocol.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EnnfuProtocol extends BaseProtocol { - public EnnfuProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EnnfuProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocol.java b/src/main/java/org/traccar/protocol/EnvotechProtocol.java index 8ccf1776f..dffa1c991 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocol.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EnvotechProtocol extends BaseProtocol { - public EnvotechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EnvotechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java index e63e7ee5f..0ed80dc6f 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocol.java +++ b/src/main/java/org/traccar/protocol/EsealProtocol.java @@ -24,14 +24,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EsealProtocol extends BaseProtocol { - public EsealProtocol() { + @Inject + public EsealProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/EskyProtocol.java b/src/main/java/org/traccar/protocol/EskyProtocol.java index dd81f4954..cb2f59dc8 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocol.java +++ b/src/main/java/org/traccar/protocol/EskyProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EskyProtocol extends BaseProtocol { - public EskyProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EskyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EskyFrameDecoder()); @@ -34,7 +37,7 @@ public class EskyProtocol extends BaseProtocol { pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java index 4da56a8eb..ffc941b69 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ExtremTracProtocol extends BaseProtocol { - public ExtremTracProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ExtremTracProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java index 7de8f3f62..fd2beaabb 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java @@ -22,13 +22,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class FifotrackProtocol extends BaseProtocol { - public FifotrackProtocol() { + @Inject + public FifotrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FifotrackFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/FlespiProtocol.java b/src/main/java/org/traccar/protocol/FlespiProtocol.java index 874be7f68..374cf77e2 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlespiProtocol extends BaseProtocol { - public FlespiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlespiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index 87ae8e274..088072d2d 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -24,10 +24,13 @@ import org.traccar.config.Config; import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class FlexApiProtocol extends BaseProtocol { - public FlexApiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlexApiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(5120)); diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocol.java b/src/main/java/org/traccar/protocol/FlexCommProtocol.java index 6e6e59f24..5397156cb 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlexCommProtocol extends BaseProtocol { - public FlexCommProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlexCommProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(2 + 2 + 101 + 5)); diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java index 0d6437d83..61e315af9 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlexibleReportProtocol extends BaseProtocol { - public FlexibleReportProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public FlexibleReportProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FlexibleReportProtocolDecoder(FlexibleReportProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocol.java b/src/main/java/org/traccar/protocol/FlextrackProtocol.java index f80460477..ebac8b4de 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlextrackProtocol extends BaseProtocol { - public FlextrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlextrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); diff --git a/src/main/java/org/traccar/protocol/FoxProtocol.java b/src/main/java/org/traccar/protocol/FoxProtocol.java index a91c2b2c5..fa45b3817 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocol.java +++ b/src/main/java/org/traccar/protocol/FoxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FoxProtocol extends BaseProtocol { - public FoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "")); diff --git a/src/main/java/org/traccar/protocol/FreedomProtocol.java b/src/main/java/org/traccar/protocol/FreedomProtocol.java index 6a7a2d72e..dac117c04 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocol.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FreedomProtocol extends BaseProtocol { - public FreedomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FreedomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocol.java b/src/main/java/org/traccar/protocol/FreematicsProtocol.java index 0220b2030..dce4994ab 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FreematicsProtocol extends BaseProtocol { - public FreematicsProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public FreematicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocol.java b/src/main/java/org/traccar/protocol/FutureWayProtocol.java index 7d2160345..715dd3c9c 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocol.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FutureWayProtocol extends BaseProtocol { - public FutureWayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FutureWayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FutureWayFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java index a3cda7fa1..90e95574a 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocol.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java @@ -21,13 +21,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GalileoProtocol extends BaseProtocol { - public GalileoProtocol() { + @Inject + public GalileoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index a123b36ec..7341b69a3 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -21,17 +21,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GatorProtocol extends BaseProtocol { - public GatorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GatorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GenxProtocol.java b/src/main/java/org/traccar/protocol/GenxProtocol.java index 5bd89c512..97d8633a0 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocol.java +++ b/src/main/java/org/traccar/protocol/GenxProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GenxProtocol extends BaseProtocol { - public GenxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GenxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Gl100Protocol.java b/src/main/java/org/traccar/protocol/Gl100Protocol.java index 91b039467..e1748c9a0 100644 --- a/src/main/java/org/traccar/protocol/Gl100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl100Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gl100Protocol extends BaseProtocol { - public Gl100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gl100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); @@ -35,7 +38,7 @@ public class Gl100Protocol extends BaseProtocol { pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java index 4d74e3116..c7b6a8e7c 100644 --- a/src/main/java/org/traccar/protocol/Gl200Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java @@ -22,16 +22,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gl200Protocol extends BaseProtocol { - public Gl200Protocol() { + @Inject + public Gl200Protocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gl200FrameDecoder()); @@ -40,7 +43,7 @@ public class Gl200Protocol extends BaseProtocol { pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java index d5e3a483b..16b99f426 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java @@ -24,14 +24,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GlobalSatProtocol extends BaseProtocol { - public GlobalSatProtocol() { + @Inject + public GlobalSatProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ALARM_DISMISS, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "!\r\n", "!")); diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java index e829ff37e..293f5fda5 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GlobalstarProtocol extends BaseProtocol { - public GlobalstarProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GlobalstarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/GnxProtocol.java b/src/main/java/org/traccar/protocol/GnxProtocol.java index c51888336..32d642688 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocol.java +++ b/src/main/java/org/traccar/protocol/GnxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GnxProtocol extends BaseProtocol { - public GnxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GnxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\n\r")); diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocol.java b/src/main/java/org/traccar/protocol/GoSafeProtocol.java index 35216436a..607931500 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocol.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GoSafeProtocol extends BaseProtocol { - public GoSafeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GoSafeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); @@ -35,7 +38,7 @@ public class GoSafeProtocol extends BaseProtocol { pipeline.addLast(new GoSafeProtocolDecoder(GoSafeProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GotopProtocol.java b/src/main/java/org/traccar/protocol/GotopProtocol.java index e2fe4ff93..53fcea0d0 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocol.java +++ b/src/main/java/org/traccar/protocol/GotopProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GotopProtocol extends BaseProtocol { - public GotopProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GotopProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/Gps056Protocol.java b/src/main/java/org/traccar/protocol/Gps056Protocol.java index fa7e5c12e..dbffbfdbb 100644 --- a/src/main/java/org/traccar/protocol/Gps056Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps056Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gps056Protocol extends BaseProtocol { - public Gps056Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gps056Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gps056FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java index bf0b01526..2725494c5 100644 --- a/src/main/java/org/traccar/protocol/Gps103Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gps103Protocol extends BaseProtocol { - public Gps103Protocol() { + @Inject + public Gps103Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -37,7 +40,7 @@ public class Gps103Protocol extends BaseProtocol { Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*")); @@ -47,7 +50,7 @@ public class Gps103Protocol extends BaseProtocol { pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocol.java b/src/main/java/org/traccar/protocol/GpsGateProtocol.java index 51dbae7e3..a6a73ae6b 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GpsGateProtocol extends BaseProtocol { - public GpsGateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GpsGateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\0", "\n", "\r\n")); diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java index 3a0c1aeb9..12b53342c 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GpsMarkerProtocol extends BaseProtocol { - public GpsMarkerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GpsMarkerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java index 68241958b..a474b1e53 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GpsmtaProtocol extends BaseProtocol { - public GpsmtaProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public GpsmtaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java index 58c3d1ba4..bb66501e2 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocol.java +++ b/src/main/java/org/traccar/protocol/GranitProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GranitProtocol extends BaseProtocol { - public GranitProtocol() { + @Inject + public GranitProtocol(Config config) { setSupportedDataCommands( Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE, @@ -33,7 +36,7 @@ public class GranitProtocol extends BaseProtocol { setSupportedTextCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GranitFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Gs100Protocol.java b/src/main/java/org/traccar/protocol/Gs100Protocol.java index bd7c21b57..425ca9330 100644 --- a/src/main/java/org/traccar/protocol/Gs100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gs100Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gs100Protocol extends BaseProtocol { - public Gs100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gs100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gs100ProtocolDecoder(Gs100Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gt02Protocol.java b/src/main/java/org/traccar/protocol/Gt02Protocol.java index c57de2fd6..fa05761f6 100644 --- a/src/main/java/org/traccar/protocol/Gt02Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt02Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gt02Protocol extends BaseProtocol { - public Gt02Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gt02Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java index 48eb77c0c..38278121c 100644 --- a/src/main/java/org/traccar/protocol/Gt06Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java @@ -21,14 +21,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gt06Protocol extends BaseProtocol { - public Gt06Protocol() { + @Inject + public Gt06Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gt06FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Gt30Protocol.java b/src/main/java/org/traccar/protocol/Gt30Protocol.java index da401acd1..6b79ba58b 100644 --- a/src/main/java/org/traccar/protocol/Gt30Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt30Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gt30Protocol extends BaseProtocol { - public Gt30Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gt30Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java index d35333171..4e5f8c96a 100644 --- a/src/main/java/org/traccar/protocol/H02Protocol.java +++ b/src/main/java/org/traccar/protocol/H02Protocol.java @@ -23,9 +23,12 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; +import javax.inject.Inject; + public class H02Protocol extends BaseProtocol { - public H02Protocol() { + @Inject + public H02Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, @@ -33,7 +36,7 @@ public class H02Protocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME, Command.TYPE_POSITION_PERIODIC ); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { int messageLength = config.getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); @@ -43,7 +46,7 @@ public class H02Protocol extends BaseProtocol { pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/HaicomProtocol.java b/src/main/java/org/traccar/protocol/HaicomProtocol.java index c03c3c0b3..f56c605f0 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocol.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HaicomProtocol extends BaseProtocol { - public HaicomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HaicomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '*')); diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocol.java b/src/main/java/org/traccar/protocol/HomtecsProtocol.java index 85e4012a2..aa2d7d852 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocol.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HomtecsProtocol extends BaseProtocol { - public HomtecsProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public HomtecsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java index 8795ed727..02d8e5a8e 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HoopoProtocol extends BaseProtocol { - public HoopoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HoopoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index bf3b2052a..b1b61e977 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HuaShengProtocol extends BaseProtocol { - public HuaShengProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HuaShengProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuaShengFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java index 0e1ab0b02..c37918b0e 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java @@ -21,13 +21,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class HuabaoProtocol extends BaseProtocol { - public HuabaoProtocol() { + @Inject + public HuabaoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/HunterProProtocol.java b/src/main/java/org/traccar/protocol/HunterProProtocol.java index e0f8bab28..ed4289d73 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocol.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HunterProProtocol extends BaseProtocol { - public HunterProProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HunterProProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); diff --git a/src/main/java/org/traccar/protocol/IdplProtocol.java b/src/main/java/org/traccar/protocol/IdplProtocol.java index 5dda72c64..aa1f4ff5b 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocol.java +++ b/src/main/java/org/traccar/protocol/IdplProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class IdplProtocol extends BaseProtocol { - public IdplProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IdplProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocol.java b/src/main/java/org/traccar/protocol/IntellitracProtocol.java index c39be0fd0..b1a91cca9 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocol.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class IntellitracProtocol extends BaseProtocol { - public IntellitracProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IntellitracProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new IntellitracFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/IotmProtocol.java b/src/main/java/org/traccar/protocol/IotmProtocol.java index b59d0ff3d..0d288f4bf 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocol.java +++ b/src/main/java/org/traccar/protocol/IotmProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class IotmProtocol extends BaseProtocol { - public IotmProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IotmProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(MqttEncoder.INSTANCE); diff --git a/src/main/java/org/traccar/protocol/ItsProtocol.java b/src/main/java/org/traccar/protocol/ItsProtocol.java index 76097b20f..5148e8ab0 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocol.java +++ b/src/main/java/org/traccar/protocol/ItsProtocol.java @@ -23,13 +23,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class ItsProtocol extends BaseProtocol { - public ItsProtocol() { + @Inject + public ItsProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ItsFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Ivt401Protocol.java b/src/main/java/org/traccar/protocol/Ivt401Protocol.java index 2ef3ea2bf..763457641 100644 --- a/src/main/java/org/traccar/protocol/Ivt401Protocol.java +++ b/src/main/java/org/traccar/protocol/Ivt401Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Ivt401Protocol extends BaseProtocol { - public Ivt401Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Ivt401Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); diff --git a/src/main/java/org/traccar/protocol/JidoProtocol.java b/src/main/java/org/traccar/protocol/JidoProtocol.java index 1040b45b9..78aa6c81c 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocol.java +++ b/src/main/java/org/traccar/protocol/JidoProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class JidoProtocol extends BaseProtocol { - public JidoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public JidoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java index c27dde8f1..30c8e9977 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java @@ -1,6 +1,6 @@ /* + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Nyash (nyashh@gmail.com) - * Copyright 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. @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class JpKorjarProtocol extends BaseProtocol { - public JpKorjarProtocol() { - addServer(new TrackerServer(false, this.getName()) { + @Inject + public JpKorjarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JpKorjarFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java index 7bc88de21..bf0b3379e 100644 --- a/src/main/java/org/traccar/protocol/Jt600Protocol.java +++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java @@ -22,15 +22,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Jt600Protocol extends BaseProtocol { - public Jt600Protocol() { + @Inject + public Jt600Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP, Command.TYPE_SET_TIMEZONE, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Jt600FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/KenjiProtocol.java b/src/main/java/org/traccar/protocol/KenjiProtocol.java index 91d5cf5b6..8d78c8c56 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocol.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocol.java @@ -24,10 +24,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class KenjiProtocol extends BaseProtocol { - public KenjiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public KenjiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java index 835d4ea0b..521274de5 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocol.java +++ b/src/main/java/org/traccar/protocol/KhdProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class KhdProtocol extends BaseProtocol { - public KhdProtocol() { + @Inject + public KhdProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, @@ -34,7 +37,7 @@ public class KhdProtocol extends BaseProtocol { Command.TYPE_SET_ODOMETER, Command.TYPE_POSITION_SINGLE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2)); diff --git a/src/main/java/org/traccar/protocol/L100Protocol.java b/src/main/java/org/traccar/protocol/L100Protocol.java index 44770c316..0edea6095 100644 --- a/src/main/java/org/traccar/protocol/L100Protocol.java +++ b/src/main/java/org/traccar/protocol/L100Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class L100Protocol extends BaseProtocol { - public L100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public L100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new L100FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/LacakProtocol.java b/src/main/java/org/traccar/protocol/LacakProtocol.java index a22ba609d..bbebd51ed 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocol.java +++ b/src/main/java/org/traccar/protocol/LacakProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class LacakProtocol extends BaseProtocol { - public LacakProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public LacakProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java index 973dcac06..249d3bcbe 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocol.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java @@ -24,16 +24,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class LaipacProtocol extends BaseProtocol { - public LaipacProtocol() { + @Inject + public LaipacProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java index b121da2df..7e13e23d0 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -24,10 +24,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class LeafSpyProtocol extends BaseProtocol { - public LeafSpyProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public LeafSpyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/M2cProtocol.java b/src/main/java/org/traccar/protocol/M2cProtocol.java index 696823460..a23ea0f57 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocol.java +++ b/src/main/java/org/traccar/protocol/M2cProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class M2cProtocol extends BaseProtocol { - public M2cProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public M2cProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, ']')); diff --git a/src/main/java/org/traccar/protocol/M2mProtocol.java b/src/main/java/org/traccar/protocol/M2mProtocol.java index e21b61b91..6809d800c 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocol.java +++ b/src/main/java/org/traccar/protocol/M2mProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class M2mProtocol extends BaseProtocol { - public M2mProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public M2mProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(23)); diff --git a/src/main/java/org/traccar/protocol/MaestroProtocol.java b/src/main/java/org/traccar/protocol/MaestroProtocol.java index 536f50448..38a67f9a4 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocol.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MaestroProtocol extends BaseProtocol { - public MaestroProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MaestroProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(160)); diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocol.java b/src/main/java/org/traccar/protocol/ManPowerProtocol.java index 8e640d137..492e86605 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ManPowerProtocol extends BaseProtocol { - public ManPowerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ManPowerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); diff --git a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java index 6e92d0809..cf65a2db3 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java +++ b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Mavlink2Protocol extends BaseProtocol { - public Mavlink2Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public Mavlink2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 1, 10, 0)); diff --git a/src/main/java/org/traccar/protocol/MegastekProtocol.java b/src/main/java/org/traccar/protocol/MegastekProtocol.java index 130697859..10215eb7c 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocol.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MegastekProtocol extends BaseProtocol { - public MegastekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MegastekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MegastekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index 6ef13c51f..2c853f0e1 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -21,9 +21,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MeiligaoProtocol extends BaseProtocol { - public MeiligaoProtocol() { + @Inject + public MeiligaoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, @@ -33,7 +36,7 @@ public class MeiligaoProtocol extends BaseProtocol { Command.TYPE_SET_TIMEZONE, Command.TYPE_REQUEST_PHOTO, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoFrameDecoder()); @@ -41,7 +44,7 @@ public class MeiligaoProtocol extends BaseProtocol { pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index 6503fa5e2..c6eba8fe1 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MeitrackProtocol extends BaseProtocol { - public MeitrackProtocol() { + @Inject + public MeitrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, @@ -33,7 +36,7 @@ public class MeitrackProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM, Command.TYPE_REQUEST_PHOTO, Command.TYPE_SEND_SMS); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeitrackFrameDecoder()); @@ -42,7 +45,7 @@ public class MeitrackProtocol extends BaseProtocol { pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java index 0d1b26909..ccbc4db4c 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MictrackProtocol extends BaseProtocol { - public MictrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MictrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); @@ -33,7 +36,7 @@ public class MictrackProtocol extends BaseProtocol { pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocol.java b/src/main/java/org/traccar/protocol/MilesmateProtocol.java index cc059c520..59212e791 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocol.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MilesmateProtocol extends BaseProtocol { - public MilesmateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MilesmateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index 182b5cd91..44599accc 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MiniFinderProtocol extends BaseProtocol { - public MiniFinderProtocol() { + @Inject + public MiniFinderProtocol(Config config) { setSupportedDataCommands( Command.TYPE_SET_TIMEZONE, Command.TYPE_VOICE_MONITORING, @@ -39,7 +42,7 @@ public class MiniFinderProtocol extends BaseProtocol { Command.TYPE_MODE_DEEP_SLEEP, Command.TYPE_SOS_NUMBER, Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\0", ";")); diff --git a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index 82341e9d0..5499a274e 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class Minifinder2Protocol extends BaseProtocol { - public Minifinder2Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Minifinder2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1200, 2, 2, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index 37e3d9131..1b06c2249 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocol.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MobilogixProtocol extends BaseProtocol { - public MobilogixProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MobilogixProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ']')); diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocol.java b/src/main/java/org/traccar/protocol/MoovboxProtocol.java index 00fcac6ed..16438e122 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocol.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MoovboxProtocol extends BaseProtocol { - public MoovboxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MoovboxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/MotorProtocol.java b/src/main/java/org/traccar/protocol/MotorProtocol.java index d168835bb..3101c9b75 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocol.java +++ b/src/main/java/org/traccar/protocol/MotorProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MotorProtocol extends BaseProtocol { - public MotorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MotorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Mta6Protocol.java b/src/main/java/org/traccar/protocol/Mta6Protocol.java index 689ee65dd..019fe4fa9 100644 --- a/src/main/java/org/traccar/protocol/Mta6Protocol.java +++ b/src/main/java/org/traccar/protocol/Mta6Protocol.java @@ -24,10 +24,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.config.Keys; +import javax.inject.Inject; + public class Mta6Protocol extends BaseProtocol { - public Mta6Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Mta6Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/MtxProtocol.java b/src/main/java/org/traccar/protocol/MtxProtocol.java index c22eb4b96..e085b6221 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocol.java +++ b/src/main/java/org/traccar/protocol/MtxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MtxProtocol extends BaseProtocol { - public MtxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MtxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/MxtProtocol.java b/src/main/java/org/traccar/protocol/MxtProtocol.java index 8269f3f2c..1190bf527 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocol.java +++ b/src/main/java/org/traccar/protocol/MxtProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MxtProtocol extends BaseProtocol { - public MxtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MxtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MxtFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavigilProtocol.java b/src/main/java/org/traccar/protocol/NavigilProtocol.java index e5e3417e9..46a6c33a5 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocol.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavigilProtocol extends BaseProtocol { - public NavigilProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavigilProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavigilFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavisProtocol.java b/src/main/java/org/traccar/protocol/NavisProtocol.java index 146f0cc9f..640a77803 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavisProtocol extends BaseProtocol { - public NavisProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavisProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java index 6423dd401..388f141f8 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavisetProtocol extends BaseProtocol { - public NavisetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavisetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisetFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index dfc08ece2..50013d1a4 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavtelecomProtocol extends BaseProtocol { - public NavtelecomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavtelecomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavtelecomFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NeosProtocol.java b/src/main/java/org/traccar/protocol/NeosProtocol.java index a3d79f833..0787b6562 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocol.java +++ b/src/main/java/org/traccar/protocol/NeosProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NeosProtocol extends BaseProtocol { - public NeosProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public NeosProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/NetProtocol.java b/src/main/java/org/traccar/protocol/NetProtocol.java index c39e07337..f27e4afb8 100644 --- a/src/main/java/org/traccar/protocol/NetProtocol.java +++ b/src/main/java/org/traccar/protocol/NetProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NetProtocol extends BaseProtocol { - public NetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '!')); diff --git a/src/main/java/org/traccar/protocol/NiotProtocol.java b/src/main/java/org/traccar/protocol/NiotProtocol.java index 659395638..0fbe0c689 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocol.java +++ b/src/main/java/org/traccar/protocol/NiotProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NiotProtocol extends BaseProtocol { - public NiotProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NiotProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java index adeab8a75..626991029 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocol.java +++ b/src/main/java/org/traccar/protocol/NoranProtocol.java @@ -21,16 +21,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class NoranProtocol extends BaseProtocol { - public NoranProtocol() { + @Inject + public NoranProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NoranProtocolEncoder(NoranProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/NvsProtocol.java b/src/main/java/org/traccar/protocol/NvsProtocol.java index 594b2c325..7ed488e38 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocol.java +++ b/src/main/java/org/traccar/protocol/NvsProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NvsProtocol extends BaseProtocol { - public NvsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NvsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NvsFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NyitechProtocol.java b/src/main/java/org/traccar/protocol/NyitechProtocol.java index da0a0331c..e7ef10945 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocol.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class NyitechProtocol extends BaseProtocol { - public NyitechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NyitechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java index b8ea7433a..94f450426 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ObdDongleProtocol extends BaseProtocol { - public ObdDongleProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ObdDongleProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1099, 20, 2, 3, 0)); diff --git a/src/main/java/org/traccar/protocol/OigoProtocol.java b/src/main/java/org/traccar/protocol/OigoProtocol.java index 02d5c40ff..0539bada6 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocol.java +++ b/src/main/java/org/traccar/protocol/OigoProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OigoProtocol extends BaseProtocol { - public OigoProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public OigoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OigoProtocolDecoder(OigoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/OkoProtocol.java b/src/main/java/org/traccar/protocol/OkoProtocol.java index 70ea65a29..29c8bc1b9 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocol.java +++ b/src/main/java/org/traccar/protocol/OkoProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OkoProtocol extends BaseProtocol { - public OkoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OkoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '}')); diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocol.java b/src/main/java/org/traccar/protocol/OmnicommProtocol.java index 81a7b30ac..dd400c779 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocol.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OmnicommProtocol extends BaseProtocol { - public OmnicommProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OmnicommProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OmnicommFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java index 1eed96eed..5443b4ffc 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OpenGtsProtocol extends BaseProtocol { - public OpenGtsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OpenGtsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java index 4f27b1efe..fb09f0abb 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocol.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerClient; import org.traccar.config.Config; +import javax.inject.Inject; + public class OrbcommProtocol extends BaseProtocol { - public OrbcommProtocol() { - addClient(new TrackerClient(getName()) { + @Inject + public OrbcommProtocol(Config config) { + addClient(new TrackerClient(config, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpRequestEncoder()); diff --git a/src/main/java/org/traccar/protocol/OrionProtocol.java b/src/main/java/org/traccar/protocol/OrionProtocol.java index cb92f10b7..2dec7cd06 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocol.java +++ b/src/main/java/org/traccar/protocol/OrionProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OrionProtocol extends BaseProtocol { - public OrionProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OrionProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OrionFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocol.java b/src/main/java/org/traccar/protocol/OsmAndProtocol.java index 3281a8ae4..a86bc70d7 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocol.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OsmAndProtocol extends BaseProtocol { - public OsmAndProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OsmAndProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocol.java b/src/main/java/org/traccar/protocol/OutsafeProtocol.java index ae7cb881f..0099be456 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocol.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OutsafeProtocol extends BaseProtocol { - public OutsafeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OutsafeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java index c444f453e..9ad337f19 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java @@ -24,10 +24,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OwnTracksProtocol extends BaseProtocol { - public OwnTracksProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OwnTracksProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java index c8b046f41..709729ef1 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PacificTrackProtocol extends BaseProtocol { - public PacificTrackProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public PacificTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PacificTrackProtocolDecoder(PacificTrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocol.java b/src/main/java/org/traccar/protocol/PathAwayProtocol.java index a2f152dda..1d13eea95 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocol.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PathAwayProtocol extends BaseProtocol { - public PathAwayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PathAwayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocol.java b/src/main/java/org/traccar/protocol/PiligrimProtocol.java index 7c0ecaf30..aa45a0def 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocol.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PiligrimProtocol extends BaseProtocol { - public PiligrimProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PiligrimProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java index 2d21f8b41..b2101b18d 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocol.java +++ b/src/main/java/org/traccar/protocol/PluginProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PluginProtocol extends BaseProtocol { - public PluginProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PluginProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/PolteProtocol.java b/src/main/java/org/traccar/protocol/PolteProtocol.java index 47c64e5ba..69666cc0e 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocol.java +++ b/src/main/java/org/traccar/protocol/PolteProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PolteProtocol extends BaseProtocol { - public PolteProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PolteProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PortmanProtocol.java b/src/main/java/org/traccar/protocol/PortmanProtocol.java index 875c0a599..de78013fa 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocol.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocol.java @@ -24,13 +24,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PortmanProtocol extends BaseProtocol { - public PortmanProtocol() { + @Inject + public PortmanProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java index db1b6d918..b77dd97bf 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocol.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java @@ -24,13 +24,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PretraceProtocol extends BaseProtocol { - public PretraceProtocol() { + @Inject + public PretraceProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); diff --git a/src/main/java/org/traccar/protocol/PricolProtocol.java b/src/main/java/org/traccar/protocol/PricolProtocol.java index b009662ac..f5e904541 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocol.java +++ b/src/main/java/org/traccar/protocol/PricolProtocol.java @@ -21,17 +21,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PricolProtocol extends BaseProtocol { - public PricolProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PricolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(64)); pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ProgressProtocol.java b/src/main/java/org/traccar/protocol/ProgressProtocol.java index 235ae1c5e..49eb6847f 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocol.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class ProgressProtocol extends BaseProtocol { - public ProgressProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ProgressProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/PstProtocol.java b/src/main/java/org/traccar/protocol/PstProtocol.java index e1f3e18ce..73f978cbd 100644 --- a/src/main/java/org/traccar/protocol/PstProtocol.java +++ b/src/main/java/org/traccar/protocol/PstProtocol.java @@ -21,20 +21,23 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PstProtocol extends BaseProtocol { - public PstProtocol() { + @Inject + public PstProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); pipeline.addLast(new PstProtocolDecoder(PstProtocol.this)); } }); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstFrameEncoder()); diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java index c134afa51..b272582a4 100644 --- a/src/main/java/org/traccar/protocol/Pt215Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Pt215Protocol extends BaseProtocol { - public Pt215Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt215Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 1, -1, 0)); diff --git a/src/main/java/org/traccar/protocol/Pt3000Protocol.java b/src/main/java/org/traccar/protocol/Pt3000Protocol.java index 1f783481b..d72774f47 100644 --- a/src/main/java/org/traccar/protocol/Pt3000Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt3000Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Pt3000Protocol extends BaseProtocol { - public Pt3000Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt3000Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java index 64ff4fe06..d5d30e8e8 100644 --- a/src/main/java/org/traccar/protocol/Pt502Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java @@ -22,16 +22,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Pt502Protocol extends BaseProtocol { - public Pt502Protocol() { + @Inject + public Pt502Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_SET_TIMEZONE, Command.TYPE_ALARM_SPEED, Command.TYPE_OUTPUT_CONTROL, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Pt502FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Pt60Protocol.java b/src/main/java/org/traccar/protocol/Pt60Protocol.java index 45084a2f3..58345f025 100644 --- a/src/main/java/org/traccar/protocol/Pt60Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt60Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Pt60Protocol extends BaseProtocol { - public Pt60Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt60Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@", "@E#@")); diff --git a/src/main/java/org/traccar/protocol/R12wProtocol.java b/src/main/java/org/traccar/protocol/R12wProtocol.java index f3464a3a3..a406f6306 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocol.java +++ b/src/main/java/org/traccar/protocol/R12wProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class R12wProtocol extends BaseProtocol { - public R12wProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public R12wProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java index 7c7b9a87d..63ca3476c 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RaceDynamicsProtocol extends BaseProtocol { - public RaceDynamicsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RaceDynamicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1500)); diff --git a/src/main/java/org/traccar/protocol/RadarProtocol.java b/src/main/java/org/traccar/protocol/RadarProtocol.java index 0b3d836a5..9d88c6d72 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocol.java +++ b/src/main/java/org/traccar/protocol/RadarProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RadarProtocol extends BaseProtocol { - public RadarProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RadarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 12, 2, -14, 0)); diff --git a/src/main/java/org/traccar/protocol/RaveonProtocol.java b/src/main/java/org/traccar/protocol/RaveonProtocol.java index 5a1bb88d2..db70396ee 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocol.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RaveonProtocol extends BaseProtocol { - public RaveonProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RaveonProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/RecodaProtocol.java b/src/main/java/org/traccar/protocol/RecodaProtocol.java index 9ae837a88..0d50db01e 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocol.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class RecodaProtocol extends BaseProtocol { - public RecodaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RecodaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 4, 4, -8, 0, true)); diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java index efea6013e..1d4b419bb 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RetranslatorProtocol extends BaseProtocol { - public RetranslatorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RetranslatorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RetranslatorFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/RitiProtocol.java b/src/main/java/org/traccar/protocol/RitiProtocol.java index 34c4015b2..9b9c00cb2 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocol.java +++ b/src/main/java/org/traccar/protocol/RitiProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class RitiProtocol extends BaseProtocol { - public RitiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RitiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 105, 2, 3, 0, true)); diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java index 099136272..ab2bc5842 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RoboTrackProtocol extends BaseProtocol { - public RoboTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RoboTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RoboTrackFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java index 3a52a215e..109d91b16 100644 --- a/src/main/java/org/traccar/protocol/RstProtocol.java +++ b/src/main/java/org/traccar/protocol/RstProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RstProtocol extends BaseProtocol { - public RstProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public RstProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java index 59c5f7942..99a9686f6 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class RuptelaProtocol extends BaseProtocol { - public RuptelaProtocol() { + @Inject + public RuptelaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ENGINE_STOP, @@ -36,7 +39,7 @@ public class RuptelaProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL, Command.TYPE_SET_CONNECTION, Command.TYPE_SET_ODOMETER); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/S168Protocol.java b/src/main/java/org/traccar/protocol/S168Protocol.java index 7186ce93d..f904ed9ff 100644 --- a/src/main/java/org/traccar/protocol/S168Protocol.java +++ b/src/main/java/org/traccar/protocol/S168Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class S168Protocol extends BaseProtocol { - public S168Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public S168Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); diff --git a/src/main/java/org/traccar/protocol/SabertekProtocol.java b/src/main/java/org/traccar/protocol/SabertekProtocol.java index 9c66fd50d..403243cdc 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocol.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SabertekProtocol extends BaseProtocol { - public SabertekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SabertekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SabertekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/SanavProtocol.java b/src/main/java/org/traccar/protocol/SanavProtocol.java index e067a2469..1a0e7b0e9 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocol.java +++ b/src/main/java/org/traccar/protocol/SanavProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SanavProtocol extends BaseProtocol { - public SanavProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SanavProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); @@ -33,7 +36,7 @@ public class SanavProtocol extends BaseProtocol { pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SanulProtocol.java b/src/main/java/org/traccar/protocol/SanulProtocol.java index 3c268d984..ea44bf868 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocol.java +++ b/src/main/java/org/traccar/protocol/SanulProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class SanulProtocol extends BaseProtocol { - public SanulProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SanulProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); diff --git a/src/main/java/org/traccar/protocol/SatsolProtocol.java b/src/main/java/org/traccar/protocol/SatsolProtocol.java index 15a43f94d..d90033e38 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocol.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class SatsolProtocol extends BaseProtocol { - public SatsolProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SatsolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1400, 8, 2, 0, 0, true)); diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocol.java b/src/main/java/org/traccar/protocol/SigfoxProtocol.java index 7666f5589..9a268af62 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocol.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SigfoxProtocol extends BaseProtocol { - public SigfoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SigfoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/SiwiProtocol.java b/src/main/java/org/traccar/protocol/SiwiProtocol.java index 4cb441e8a..f12958a50 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocol.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SiwiProtocol extends BaseProtocol { - public SiwiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SiwiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java index 91830504e..7ae26f634 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SkypatrolProtocol extends BaseProtocol { - public SkypatrolProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public SkypatrolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SkypatrolProtocolDecoder(SkypatrolProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java index 6ae341db3..cb7efb7ee 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SmartSoleProtocol extends BaseProtocol { - public SmartSoleProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SmartSoleProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocol.java b/src/main/java/org/traccar/protocol/SmokeyProtocol.java index dc7da9ab5..22b343537 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocol.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SmokeyProtocol extends BaseProtocol { - public SmokeyProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public SmokeyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SmokeyProtocolDecoder(SmokeyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java index 9f9ef5a87..0676aa629 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SolarPoweredProtocol extends BaseProtocol { - public SolarPoweredProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SolarPoweredProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/SpotProtocol.java b/src/main/java/org/traccar/protocol/SpotProtocol.java index 238dc3b72..6bd802fed 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocol.java +++ b/src/main/java/org/traccar/protocol/SpotProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SpotProtocol extends BaseProtocol { - public SpotProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SpotProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocol.java b/src/main/java/org/traccar/protocol/StarLinkProtocol.java index fa9cdc30a..d578fa705 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocol.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class StarLinkProtocol extends BaseProtocol { - public StarLinkProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public StarLinkProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/StarcomProtocol.java b/src/main/java/org/traccar/protocol/StarcomProtocol.java index 8f1c4bc3f..33c3a4776 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocol.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class StarcomProtocol extends BaseProtocol { - public StarcomProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public StarcomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/StartekProtocol.java b/src/main/java/org/traccar/protocol/StartekProtocol.java index 14ae1564e..d010df858 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocol.java +++ b/src/main/java/org/traccar/protocol/StartekProtocol.java @@ -24,15 +24,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class StartekProtocol extends BaseProtocol { - public StartekProtocol() { + @Inject + public StartekProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_OUTPUT_CONTROL, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index 206b29e29..af4e0d2c4 100644 --- a/src/main/java/org/traccar/protocol/StbProtocol.java +++ b/src/main/java/org/traccar/protocol/StbProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class StbProtocol extends BaseProtocol { - public StbProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public StbProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Stl060Protocol.java b/src/main/java/org/traccar/protocol/Stl060Protocol.java index 0ac0490e3..83b5db3bb 100644 --- a/src/main/java/org/traccar/protocol/Stl060Protocol.java +++ b/src/main/java/org/traccar/protocol/Stl060Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Stl060Protocol extends BaseProtocol { - public Stl060Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Stl060Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Stl060FrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java index ae55d2a14..4253b761b 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocol.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class SuntechProtocol extends BaseProtocol { - public SuntechProtocol() { + @Inject + public SuntechProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL, Command.TYPE_REBOOT_DEVICE, @@ -33,7 +36,7 @@ public class SuntechProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SuntechFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/SupermateProtocol.java b/src/main/java/org/traccar/protocol/SupermateProtocol.java index 59c68d7d0..4290b7126 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocol.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SupermateProtocol extends BaseProtocol { - public SupermateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SupermateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#")); diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java index d9b413a9e..7c6624f7c 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocol.java +++ b/src/main/java/org/traccar/protocol/SviasProtocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class SviasProtocol extends BaseProtocol { - public SviasProtocol() { + @Inject + public SviasProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -36,7 +39,7 @@ public class SviasProtocol extends BaseProtocol { Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_ALARM_REMOVE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]")); diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocol.java b/src/main/java/org/traccar/protocol/SwiftechProtocol.java index 3222a7038..68cf40d84 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocol.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SwiftechProtocol extends BaseProtocol { - public SwiftechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SwiftechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/T55Protocol.java b/src/main/java/org/traccar/protocol/T55Protocol.java index f3f7b4a74..cedac275f 100644 --- a/src/main/java/org/traccar/protocol/T55Protocol.java +++ b/src/main/java/org/traccar/protocol/T55Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class T55Protocol extends BaseProtocol { - public T55Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public T55Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); @@ -35,7 +38,7 @@ public class T55Protocol extends BaseProtocol { pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/T57Protocol.java b/src/main/java/org/traccar/protocol/T57Protocol.java index e228c5c0d..4bafe8c6d 100644 --- a/src/main/java/org/traccar/protocol/T57Protocol.java +++ b/src/main/java/org/traccar/protocol/T57Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class T57Protocol extends BaseProtocol { - public T57Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public T57Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new T57FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index a6f5f1514..253c3cb73 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.java @@ -22,12 +22,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class T800xProtocol extends BaseProtocol { - public T800xProtocol() { + @Inject + public T800xProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); @@ -35,7 +38,7 @@ public class T800xProtocol extends BaseProtocol { pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TaipProtocol.java b/src/main/java/org/traccar/protocol/TaipProtocol.java index caa4f4c97..943ec98c5 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocol.java +++ b/src/main/java/org/traccar/protocol/TaipProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TaipProtocol extends BaseProtocol { - public TaipProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TaipProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '<')); @@ -36,7 +39,7 @@ public class TaipProtocol extends BaseProtocol { pipeline.addLast(new TaipProtocolDecoder(TaipProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java index e421990a7..191dd9ccc 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocol.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TechTltProtocol extends BaseProtocol { - public TechTltProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public TechTltProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java index 48ea825a5..265a3eb64 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TechtoCruzProtocol extends BaseProtocol { - public TechtoCruzProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TechtoCruzProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TechtoCruzFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TekProtocol.java b/src/main/java/org/traccar/protocol/TekProtocol.java index 0aeab9be3..54e860d79 100644 --- a/src/main/java/org/traccar/protocol/TekProtocol.java +++ b/src/main/java/org/traccar/protocol/TekProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TekProtocol extends BaseProtocol { - public TekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocol.java b/src/main/java/org/traccar/protocol/TelemaxProtocol.java index 9bbdf7ad7..9e9cbb50e 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocol.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TelemaxProtocol extends BaseProtocol { - public TelemaxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TelemaxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/TelicProtocol.java b/src/main/java/org/traccar/protocol/TelicProtocol.java index 6d47a7a7f..9ef7864ca 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocol.java +++ b/src/main/java/org/traccar/protocol/TelicProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TelicProtocol extends BaseProtocol { - public TelicProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TelicProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TelicFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java index e2ee8ef19..38283cb64 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TeltonikaProtocol extends BaseProtocol { - public TeltonikaProtocol() { + @Inject + public TeltonikaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaFrameDecoder()); @@ -34,7 +37,7 @@ public class TeltonikaProtocol extends BaseProtocol { pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java index 8b62db8c0..73219cc5e 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TeraTrackProtocol extends BaseProtocol { - public TeraTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TeraTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java index 076386818..38bf078aa 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ThinkPowerProtocol extends BaseProtocol { - public ThinkPowerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ThinkPowerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java index 6c684a8b4..782b0a352 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ThinkRaceProtocol extends BaseProtocol { - public ThinkRaceProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ThinkRaceProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2 + 12 + 1 + 1, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/Tk102Protocol.java b/src/main/java/org/traccar/protocol/Tk102Protocol.java index 8eb923d50..150e83ab3 100644 --- a/src/main/java/org/traccar/protocol/Tk102Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk102Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tk102Protocol extends BaseProtocol { - public Tk102Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tk102Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1 + 1 + 10, 1, 1, 0)); diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java index bca16928f..cf09886f5 100644 --- a/src/main/java/org/traccar/protocol/Tk103Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Tk103Protocol extends BaseProtocol { - public Tk103Protocol() { + @Inject + public Tk103Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_GET_DEVICE_STATUS, @@ -46,7 +49,7 @@ public class Tk103Protocol extends BaseProtocol { Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Tk103FrameDecoder()); @@ -56,7 +59,7 @@ public class Tk103Protocol extends BaseProtocol { pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java index 8c8777074..b10271f7d 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tlt2hProtocol extends BaseProtocol { - public Tlt2hProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tlt2hProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); diff --git a/src/main/java/org/traccar/protocol/TlvProtocol.java b/src/main/java/org/traccar/protocol/TlvProtocol.java index 5b8de8fbe..9d83388c9 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocol.java +++ b/src/main/java/org/traccar/protocol/TlvProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TlvProtocol extends BaseProtocol { - public TlvProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TlvProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); diff --git a/src/main/java/org/traccar/protocol/TmgProtocol.java b/src/main/java/org/traccar/protocol/TmgProtocol.java index 6c29a8854..e078c425b 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocol.java +++ b/src/main/java/org/traccar/protocol/TmgProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TmgProtocol extends BaseProtocol { - public TmgProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TmgProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TmgFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocol.java b/src/main/java/org/traccar/protocol/TopflytechProtocol.java index 47162a42d..339d2fc8d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocol.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TopflytechProtocol extends BaseProtocol { - public TopflytechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TopflytechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index 3c1a7eed3..b15373d71 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocol.java +++ b/src/main/java/org/traccar/protocol/TopinProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TopinProtocol extends BaseProtocol { - public TopinProtocol() { + @Inject + public TopinProtocol(Config config) { setSupportedDataCommands( Command.TYPE_SOS_NUMBER); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TopinProtocolEncoder(TopinProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index 3322d1dc0..9ab36fd0b 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -23,9 +23,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TotemProtocol extends BaseProtocol { - public TotemProtocol() { + @Inject + public TotemProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_REBOOT_DEVICE, @@ -47,7 +50,7 @@ public class TotemProtocol extends BaseProtocol { Command.TYPE_ENGINE_STOP ); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TotemFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tr20Protocol.java b/src/main/java/org/traccar/protocol/Tr20Protocol.java index dc6c013c8..615fdab28 100644 --- a/src/main/java/org/traccar/protocol/Tr20Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr20Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tr20Protocol extends BaseProtocol { - public Tr20Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tr20Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); @@ -35,7 +38,7 @@ public class Tr20Protocol extends BaseProtocol { pipeline.addLast(new Tr20ProtocolDecoder(Tr20Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Tr900Protocol.java b/src/main/java/org/traccar/protocol/Tr900Protocol.java index 615987952..162cbe651 100644 --- a/src/main/java/org/traccar/protocol/Tr900Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr900Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tr900Protocol extends BaseProtocol { - public Tr900Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tr900Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); @@ -35,7 +38,7 @@ public class Tr900Protocol extends BaseProtocol { pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocol.java b/src/main/java/org/traccar/protocol/TrackboxProtocol.java index 1c756e26b..4236144a3 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocol.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TrackboxProtocol extends BaseProtocol { - public TrackboxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrackboxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocol.java b/src/main/java/org/traccar/protocol/TrakMateProtocol.java index 25f6d9470..b7637e6f3 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocol.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TrakMateProtocol extends BaseProtocol { - public TrakMateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrakMateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/TramigoProtocol.java b/src/main/java/org/traccar/protocol/TramigoProtocol.java index 2c8013523..79a59abd3 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocol.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TramigoProtocol extends BaseProtocol { - public TramigoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TramigoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TramigoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TrvProtocol.java b/src/main/java/org/traccar/protocol/TrvProtocol.java index a8884eb5e..e67afbda2 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocol.java +++ b/src/main/java/org/traccar/protocol/TrvProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TrvProtocol extends BaseProtocol { - public TrvProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrvProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/Tt8850Protocol.java b/src/main/java/org/traccar/protocol/Tt8850Protocol.java index b11411817..ab109e274 100644 --- a/src/main/java/org/traccar/protocol/Tt8850Protocol.java +++ b/src/main/java/org/traccar/protocol/Tt8850Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tt8850Protocol extends BaseProtocol { - public Tt8850Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tt8850Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "$")); diff --git a/src/main/java/org/traccar/protocol/TytanProtocol.java b/src/main/java/org/traccar/protocol/TytanProtocol.java index 2ca1ff8e8..cc3bc9b52 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocol.java +++ b/src/main/java/org/traccar/protocol/TytanProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TytanProtocol extends BaseProtocol { - public TytanProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public TytanProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TytanProtocolDecoder(TytanProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TzoneProtocol.java b/src/main/java/org/traccar/protocol/TzoneProtocol.java index 9bb550e39..d25757b63 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocol.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TzoneProtocol extends BaseProtocol { - public TzoneProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TzoneProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocol.java b/src/main/java/org/traccar/protocol/UlbotechProtocol.java index d149bbd58..57fc47644 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocol.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class UlbotechProtocol extends BaseProtocol { - public UlbotechProtocol() { + @Inject + public UlbotechProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new UlbotechFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/UproProtocol.java b/src/main/java/org/traccar/protocol/UproProtocol.java index 5bfa6d76d..e27088594 100644 --- a/src/main/java/org/traccar/protocol/UproProtocol.java +++ b/src/main/java/org/traccar/protocol/UproProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class UproProtocol extends BaseProtocol { - public UproProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public UproProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/UuxProtocol.java b/src/main/java/org/traccar/protocol/UuxProtocol.java index 61f622f68..3de4a4732 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocol.java +++ b/src/main/java/org/traccar/protocol/UuxProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class UuxProtocol extends BaseProtocol { - public UuxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public UuxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 1)); diff --git a/src/main/java/org/traccar/protocol/V680Protocol.java b/src/main/java/org/traccar/protocol/V680Protocol.java index 488dcc4e0..53bca849c 100644 --- a/src/main/java/org/traccar/protocol/V680Protocol.java +++ b/src/main/java/org/traccar/protocol/V680Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class V680Protocol extends BaseProtocol { - public V680Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public V680Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); @@ -35,7 +38,7 @@ public class V680Protocol extends BaseProtocol { pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocol.java b/src/main/java/org/traccar/protocol/VisiontekProtocol.java index 5d3e3c097..5296402b4 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocol.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class VisiontekProtocol extends BaseProtocol { - public VisiontekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VisiontekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/VnetProtocol.java b/src/main/java/org/traccar/protocol/VnetProtocol.java index 41522935e..dd739f0d9 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocol.java +++ b/src/main/java/org/traccar/protocol/VnetProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class VnetProtocol extends BaseProtocol { - public VnetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VnetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1500, 4, 2, 12, 0, true)); diff --git a/src/main/java/org/traccar/protocol/Vt200Protocol.java b/src/main/java/org/traccar/protocol/Vt200Protocol.java index 655514e94..efb5fe2fd 100644 --- a/src/main/java/org/traccar/protocol/Vt200Protocol.java +++ b/src/main/java/org/traccar/protocol/Vt200Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Vt200Protocol extends BaseProtocol { - public Vt200Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Vt200Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Vt200FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocol.java b/src/main/java/org/traccar/protocol/VtfmsProtocol.java index 8bedd455d..482ab4a37 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocol.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class VtfmsProtocol extends BaseProtocol { - public VtfmsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VtfmsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new VtfmsFrameDecoder()); @@ -32,7 +35,7 @@ public class VtfmsProtocol extends BaseProtocol { pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java index fe96b3828..600f81328 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocol.java +++ b/src/main/java/org/traccar/protocol/WatchProtocol.java @@ -21,9 +21,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class WatchProtocol extends BaseProtocol { - public WatchProtocol() { + @Inject + public WatchProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -41,7 +44,7 @@ public class WatchProtocol extends BaseProtocol { Command.TYPE_VOICE_MESSAGE, Command.TYPE_SET_TIMEZONE, Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WatchFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index 204bdd341..a744349cd 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -27,15 +27,18 @@ import org.traccar.model.Command; import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class WialonProtocol extends BaseProtocol { - public WialonProtocol() { + @Inject + public WialonProtocol(Config config) { setSupportedDataCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_SEND_USSD, Command.TYPE_IDENTIFICATION, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); @@ -51,7 +54,7 @@ public class WialonProtocol extends BaseProtocol { pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); diff --git a/src/main/java/org/traccar/protocol/WliProtocol.java b/src/main/java/org/traccar/protocol/WliProtocol.java index aab25abca..f7084e55b 100644 --- a/src/main/java/org/traccar/protocol/WliProtocol.java +++ b/src/main/java/org/traccar/protocol/WliProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class WliProtocol extends BaseProtocol { - public WliProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public WliProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WliFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java index dc3ed3413..5a0401df4 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocol.java +++ b/src/main/java/org/traccar/protocol/WondexProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class WondexProtocol extends BaseProtocol { - public WondexProtocol() { + @Inject + public WondexProtocol(Config config) { setSupportedDataCommands( Command.TYPE_GET_DEVICE_STATUS, Command.TYPE_GET_MODEM_STATUS, @@ -40,7 +43,7 @@ public class WondexProtocol extends BaseProtocol { Command.TYPE_POSITION_SINGLE, Command.TYPE_GET_VERSION, Command.TYPE_IDENTIFICATION); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WondexFrameDecoder()); @@ -49,7 +52,7 @@ public class WondexProtocol extends BaseProtocol { pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/WristbandProtocol.java b/src/main/java/org/traccar/protocol/WristbandProtocol.java index 38f85f45a..c5d8d4050 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocol.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class WristbandProtocol extends BaseProtocol { - public WristbandProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public WristbandProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, 3, 0)); diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index d64190ad8..4630a69e0 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Xexun2Protocol extends BaseProtocol { - public Xexun2Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Xexun2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xexun2FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java index 2e6d4393b..5c7329603 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocol.java +++ b/src/main/java/org/traccar/protocol/XexunProtocol.java @@ -25,13 +25,16 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; +import javax.inject.Inject; + public class XexunProtocol extends BaseProtocol { - public XexunProtocol() { + @Inject + public XexunProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { boolean full = config.getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java index f986ca3e6..0841d86d5 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocol.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java @@ -24,12 +24,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class XirgoProtocol extends BaseProtocol { - public XirgoProtocol() { + @Inject + public XirgoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); @@ -39,7 +42,7 @@ public class XirgoProtocol extends BaseProtocol { pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java index 53eed5595..65c2a1230 100644 --- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java +++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java @@ -26,16 +26,19 @@ import org.traccar.model.Command; import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class Xrb28Protocol extends BaseProtocol { - public Xrb28Protocol() { + @Inject + public Xrb28Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Xt013Protocol.java b/src/main/java/org/traccar/protocol/Xt013Protocol.java index aaed47c89..9e9087609 100644 --- a/src/main/java/org/traccar/protocol/Xt013Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt013Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Xt013Protocol extends BaseProtocol { - public Xt013Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Xt013Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Xt2400Protocol.java b/src/main/java/org/traccar/protocol/Xt2400Protocol.java index 81567b82c..e200adb9f 100644 --- a/src/main/java/org/traccar/protocol/Xt2400Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt2400Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Xt2400Protocol extends BaseProtocol { - public Xt2400Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public Xt2400Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xt2400ProtocolDecoder(Xt2400Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/YwtProtocol.java b/src/main/java/org/traccar/protocol/YwtProtocol.java index 6dd8623c9..fb44e2360 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocol.java +++ b/src/main/java/org/traccar/protocol/YwtProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class YwtProtocol extends BaseProtocol { - public YwtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public YwtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); -- cgit v1.2.3 From e665a2c7f4dd925bed116961da48bb018d6f57f7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 14:36:31 -0700 Subject: Remove static injector usages --- src/main/java/org/traccar/BasePipelineFactory.java | 7 +++++-- src/main/java/org/traccar/MainEventHandler.java | 8 +++++--- src/main/java/org/traccar/MainModule.java | 5 ++--- src/main/java/org/traccar/WebDataHandler.java | 9 +++++---- src/main/java/org/traccar/api/resource/DeviceResource.java | 6 +++++- src/main/java/org/traccar/database/MailManager.java | 7 ++++--- src/main/java/org/traccar/session/ConnectionManager.java | 12 ++++++------ 7 files changed, 32 insertions(+), 22 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 3eb7011a1..915c3f7ea 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -15,6 +15,7 @@ */ package org.traccar; +import com.google.inject.Injector; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInboundHandler; @@ -55,11 +56,13 @@ import java.util.Map; public abstract class BasePipelineFactory extends ChannelInitializer { + private final Injector injector; private final TrackerConnector connector; private final String protocol; private int timeout; public BasePipelineFactory(TrackerConnector connector, Config config, String protocol) { + this.injector = Main.getInjector(); this.connector = connector; this.protocol = protocol; timeout = config.getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); @@ -76,7 +79,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { private void addHandlers(ChannelPipeline pipeline, Class... handlerClasses) { for (Class handlerClass : handlerClasses) { if (handlerClass != null) { - pipeline.addLast(Main.getInjector().getInstance(handlerClass)); + pipeline.addLast(injector.getInstance(handlerClass)); } } } @@ -111,7 +114,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { addProtocolHandlers(handler -> { if (handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder) { - Main.getInjector().injectMembers(handler); + injector.injectMembers(handler); } else { if (handler instanceof ChannelInboundHandler) { handler = new WrapperInboundHandler((ChannelInboundHandler) handler); diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index d2665cbcc..965421d2f 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -55,13 +55,16 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final CacheManager cacheManager; private final Storage storage; private final ConnectionManager connectionManager; + private final StatisticsManager statisticsManager; @Inject public MainEventHandler( - Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager) { + Config config, CacheManager cacheManager, Storage storage, + ConnectionManager connectionManager, StatisticsManager statisticsManager) { this.cacheManager = cacheManager; this.storage = storage; this.connectionManager = connectionManager; + this.statisticsManager = statisticsManager; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); @@ -139,8 +142,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { } LOGGER.info(builder.toString()); - Main.getInjector().getInstance(StatisticsManager.class) - .registerMessageStored(position.getDeviceId(), position.getProtocol()); + statisticsManager.registerMessageStored(position.getDeviceId(), position.getProtocol()); } } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 3120118fc..5a5675859 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -111,9 +111,8 @@ public class MainModule extends AbstractModule { } @Provides - public static Client provideClient() { - return ClientBuilder.newClient().register( - (ContextResolver) clazz -> Main.getInjector().getInstance(ObjectMapper.class)); + public static Client provideClient(ObjectMapper objectMapper) { + return ClientBuilder.newClient().register((ContextResolver) clazz -> objectMapper); } @Singleton diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 192a15bcf..d25c4fd3c 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.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. @@ -63,6 +63,7 @@ public class WebDataHandler extends BaseDataHandler { private final CacheManager cacheManager; private final ObjectMapper objectMapper; private final Client client; + private final Timer timer; private final String url; private final String header; @@ -78,11 +79,12 @@ public class WebDataHandler extends BaseDataHandler { @Inject public WebDataHandler( - Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client) { + Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client, Timer timer) { this.cacheManager = cacheManager; this.objectMapper = objectMapper; this.client = client; + this.timer = timer; this.url = config.getString(Keys.FORWARD_URL); this.header = config.getString(Keys.FORWARD_HEADER); this.json = config.getBoolean(Keys.FORWARD_JSON); @@ -248,8 +250,7 @@ public class WebDataHandler extends BaseDataHandler { } private void schedule() { - Main.getInjector().getInstance(Timer.class).newTimeout( - this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); + timer.newTimeout(this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); } @Override diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 2509c9003..6660752d3 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -28,6 +28,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.PUT; @@ -45,6 +46,9 @@ import java.util.List; @Consumes(MediaType.APPLICATION_JSON) public class DeviceResource extends BaseObjectResource { + @Inject + private CacheManager cacheManager; + public DeviceResource() { super(Device.class); } @@ -122,7 +126,7 @@ public class DeviceResource extends BaseObjectResource { new Columns.Include("positionId"), new Condition.Equals("id", "id"))); - Main.getInjector().getInstance(CacheManager.class).updatePosition(position); + cacheManager.updatePosition(position); } else { throw new IllegalArgumentException(); } diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 54f617d5f..ac0db2d97 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -18,7 +18,6 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.config.Config; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; @@ -42,10 +41,12 @@ public final class MailManager { private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); private final Config config; + private final StatisticsManager statisticsManager; @Inject - public MailManager(Config config) { + public MailManager(Config config, StatisticsManager statisticsManager) { this.config = config; + this.statisticsManager = statisticsManager; } private static Properties getProperties(PropertiesProvider provider) { @@ -145,7 +146,7 @@ public final class MailManager { } try (Transport transport = session.getTransport()) { - Main.getInjector().getInstance(StatisticsManager.class).registerMail(); + statisticsManager.registerMail(); transport.connect( properties.getProperty("mail.smtp.host"), properties.getProperty("mail.smtp.username"), diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index cead771c9..05c4893fd 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -15,12 +15,12 @@ */ package org.traccar.session; +import com.google.inject.Injector; 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.Main; import org.traccar.Protocol; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -64,6 +64,7 @@ public class ConnectionManager { private final Map deviceStates = new ConcurrentHashMap<>(); + private final Injector injector; private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -75,8 +76,9 @@ public class ConnectionManager { @Inject public ConnectionManager( - Config config, CacheManager cacheManager, Storage storage, + Injector injector, Config config, CacheManager cacheManager, Storage storage, NotificationManager notificationManager, Timer timer) { + this.injector = injector; this.config = config; this.cacheManager = cacheManager; this.storage = storage; @@ -279,15 +281,13 @@ public class ConnectionManager { DeviceState deviceState = getDeviceState(deviceId); Map result = new HashMap<>(); - Map event = Main.getInjector() - .getInstance(MotionEventHandler.class).updateMotionState(deviceState); + Map event = injector.getInstance(MotionEventHandler.class).updateMotionState(deviceState); if (event != null) { result.putAll(event); } double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); - event = Main.getInjector().getInstance(OverspeedEventHandler.class) - .updateOverspeedState(deviceState, speedLimit); + event = injector.getInstance(OverspeedEventHandler.class).updateOverspeedState(deviceState, speedLimit); if (event != null) { result.putAll(event); } -- cgit v1.2.3 From 215a0590d3adb91a41eea48e8f7830395be03418 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 15:14:52 -0700 Subject: Make private --- src/main/java/org/traccar/database/NotificationManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 46b58dd75..92f4c818a 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -65,7 +65,7 @@ public class NotificationManager { geocodeOnRequest = config.getBoolean(Keys.GEOCODER_ON_REQUEST); } - public void updateEvent(Event event, Position position) { + private void updateEvent(Event event, Position position) { try { event.setId(storage.addObject(event, new Request(new Columns.Exclude("id")))); } catch (StorageException error) { -- cgit v1.2.3 From bea3f2131a5cd3cd2501bbd30421e402590af86a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 16:02:17 -0700 Subject: Remove unused import --- src/main/java/org/traccar/api/resource/DeviceResource.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 6660752d3..74e133f44 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -15,7 +15,6 @@ */ package org.traccar.api.resource; -import org.traccar.Main; import org.traccar.api.BaseObjectResource; import org.traccar.helper.LogAction; import org.traccar.model.Device; -- cgit v1.2.3 From 45940f73c57b871711ee9fb41ebeba3c0ca9e9b6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 16:48:15 -0700 Subject: Fix offline device notifications --- .../org/traccar/database/NotificationManager.java | 13 +++++++++++-- .../java/org/traccar/session/ConnectionManager.java | 7 +++++-- .../java/org/traccar/session/cache/CacheManager.java | 19 ++++++++++++++++--- 3 files changed, 32 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 92f4c818a..1314a3d0a 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -118,8 +118,17 @@ public class NotificationManager { } public void updateEvents(Map events) { - for (Entry event : events.entrySet()) { - updateEvent(event.getKey(), event.getValue()); + for (Entry entry : events.entrySet()) { + Event event = entry.getKey(); + Position position = entry.getValue(); + try { + cacheManager.addDevice(event.getDeviceId()); + updateEvent(event, position); + } catch (StorageException e) { + throw new RuntimeException(e); + } finally { + cacheManager.removeDevice(event.getDeviceId()); + } } } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 05c4893fd..fe6521d18 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -144,7 +144,10 @@ public class ConnectionManager { endpointSessions.put(device.getUniqueId(), deviceSession); sessionsByEndpoint.put(endpoint, endpointSessions); sessionsByDeviceId.put(device.getId(), deviceSession); - cacheManager.addDevice(device.getId()); + + if (oldSession == null) { + cacheManager.addDevice(device.getId()); + } return deviceSession; } else { @@ -190,8 +193,8 @@ public class ConnectionManager { public void deviceUnknown(long deviceId) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); - cacheManager.removeDevice(deviceId); if (deviceSession != null) { + cacheManager.removeDevice(deviceId); Endpoint endpoint = new Endpoint(deviceSession.getChannel(), deviceSession.getRemoteAddress()); sessionsByEndpoint.computeIfPresent(endpoint, (e, sessions) -> { sessions.remove(deviceSession.getUniqueId()); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 87384f746..abc8ca4c9 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -60,6 +60,7 @@ public class CacheManager { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map deviceCache = new HashMap<>(); + private final Map deviceReferences = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); private final Map devicePositions = new HashMap<>(); @@ -136,9 +137,14 @@ public class CacheManager { public void addDevice(long deviceId) throws StorageException { try { lock.writeLock().lock(); - if (!deviceLinks.containsKey(deviceId)) { + Integer references = deviceReferences.get(deviceId); + if (references != null) { + references += 1; + } else { unsafeAddDevice(deviceId); + references = 1; } + deviceReferences.put(deviceId, references); } finally { lock.writeLock().unlock(); } @@ -147,8 +153,15 @@ public class CacheManager { public void removeDevice(long deviceId) { try { lock.writeLock().lock(); - if (deviceLinks.containsKey(deviceId)) { - unsafeRemoveDevice(deviceId); + Integer references = deviceReferences.get(deviceId); + if (references != null) { + references -= 1; + if (references <= 0) { + unsafeRemoveDevice(deviceId); + deviceReferences.remove(deviceId); + } else { + deviceReferences.put(deviceId, references); + } } } finally { lock.writeLock().unlock(); -- cgit v1.2.3 From 5afb5176c63e97b1a99ef54aa7af09927fb1f3f2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Jun 2022 07:14:23 -0700 Subject: Simplify select statements --- debug.xml | 2 +- src/main/java/org/traccar/storage/DatabaseStorage.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/debug.xml b/debug.xml index 73576b20b..50e70c812 100644 --- a/debug.xml +++ b/debug.xml @@ -12,7 +12,7 @@ true true - false + true org.h2.Driver jdbc:h2:./target/database diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 052f11ad2..eec72b510 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -54,7 +54,11 @@ public class DatabaseStorage extends Storage { @Override public List getObjects(Class clazz, Request request) throws StorageException { StringBuilder query = new StringBuilder("SELECT "); - query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); + if (request.getColumns() instanceof Columns.All) { + query.append('*'); + } else { + query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); + } query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); -- cgit v1.2.3 From afae915a0db4e641e8e93b1d334d62804c83868f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Jun 2022 07:21:51 -0700 Subject: Fix login issue --- src/main/java/org/traccar/database/LoginService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java index a30e443b5..6ed45202a 100644 --- a/src/main/java/org/traccar/database/LoginService.java +++ b/src/main/java/org/traccar/database/LoginService.java @@ -52,7 +52,7 @@ public class LoginService { public User login(String email, String password) throws StorageException { User user = storage.getObject(User.class, new Request( - new Columns.Include("id", "login", "hashedPassword", "salt"), + new Columns.All(), new Condition.Or( new Condition.Equals("email", "email", email.trim()), new Condition.Equals("login", "email")))); -- cgit v1.2.3 From 009e19b44c5becefb0cb84777c2db62bf1d5005e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Jun 2022 14:40:41 -0700 Subject: Remove extra space --- src/main/java/org/traccar/database/LoginService.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java index 6ed45202a..2c541e2aa 100644 --- a/src/main/java/org/traccar/database/LoginService.java +++ b/src/main/java/org/traccar/database/LoginService.java @@ -73,7 +73,6 @@ public class LoginService { return null; } - private void checkUserEnabled(User user) throws SecurityException { if (user == null) { throw new SecurityException("Unknown account"); -- cgit v1.2.3 From f5a9207393463879cfe85e94259ee70d6d5b9980 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 07:02:42 -0700 Subject: Support service admin account --- .../org/traccar/api/resource/SessionResource.java | 2 +- .../org/traccar/api/security/LoginService.java | 94 ++++++++++++++++++++++ .../traccar/api/security/PermissionsService.java | 8 +- .../api/security/SecurityRequestFilter.java | 1 - .../traccar/api/security/ServiceAccountUser.java | 30 +++++++ src/main/java/org/traccar/config/Keys.java | 8 ++ .../java/org/traccar/database/LoginService.java | 88 -------------------- 7 files changed, 139 insertions(+), 92 deletions(-) create mode 100644 src/main/java/org/traccar/api/security/LoginService.java create mode 100644 src/main/java/org/traccar/api/security/ServiceAccountUser.java delete mode 100644 src/main/java/org/traccar/database/LoginService.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 70561f997..91052fc6b 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -16,7 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.database.LoginService; +import org.traccar.api.security.LoginService; import org.traccar.helper.DataConverter; import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java new file mode 100644 index 000000000..9938cf6dc --- /dev/null +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -0,0 +1,94 @@ +/* + * 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.api.security; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.database.LdapProvider; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +public class LoginService { + + private final Storage storage; + private final LdapProvider ldapProvider; + + private final String serviceAccountToken; + private final boolean forceLdap; + + @Inject + public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { + this.storage = storage; + this.ldapProvider = ldapProvider; + serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); + forceLdap = config.getBoolean(Keys.LDAP_FORCE); + } + + public User login(String token) throws StorageException { + if (serviceAccountToken != null && serviceAccountToken.equals(token)) { + return new ServiceAccountUser(); + } + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("token", "token", token))); + if (user != null) { + checkUserEnabled(user); + } + return user; + } + + public User login(String email, String password) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.All(), + new Condition.Or( + new Condition.Equals("email", "email", email.trim()), + new Condition.Equals("login", "email")))); + if (user != null) { + if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) + || !forceLdap && user.isPasswordValid(password)) { + checkUserEnabled(user); + return user; + } + } else { + if (ldapProvider != null && ldapProvider.login(email, password)) { + user = ldapProvider.getUser(email); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + return null; + } + + private void checkUserEnabled(User user) throws SecurityException { + if (user == null) { + throw new SecurityException("Unknown account"); + } + if (user.getDisabled()) { + throw new SecurityException("Account is disabled"); + } + if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { + throw new SecurityException("Account has expired"); + } + } + +} diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index ea7a9d572..e5bc52f22 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -58,8 +58,12 @@ public class PermissionsService { public User getUser(long userId) throws StorageException { if (user == null && userId > 0) { - user = storage.getObject( - User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + if (userId == ServiceAccountUser.ID) { + user = new ServiceAccountUser(); + } else { + user = storage.getObject( + User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + } } return user; } diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index 3413175c8..eaf5b28c4 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -18,7 +18,6 @@ package org.traccar.api.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.resource.SessionResource; -import org.traccar.database.LoginService; import org.traccar.database.StatisticsManager; import org.traccar.helper.DataConverter; import org.traccar.model.User; diff --git a/src/main/java/org/traccar/api/security/ServiceAccountUser.java b/src/main/java/org/traccar/api/security/ServiceAccountUser.java new file mode 100644 index 000000000..644142434 --- /dev/null +++ b/src/main/java/org/traccar/api/security/ServiceAccountUser.java @@ -0,0 +1,30 @@ +/* + * 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.api.security; + +import org.traccar.model.User; + +public class ServiceAccountUser extends User { + + public static final long ID = 9000000000000000000L; + + public ServiceAccountUser() { + setId(ID); + setName("Service Account"); + setEmail("none"); + setAdministrator(true); + } +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index a03e47022..3f52fbd96 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -673,6 +673,14 @@ public final class Keys { "web.debug", List.of(KeyType.CONFIG)); + /** + * A token to login as a virtual admin account. Can be used to restore access in case of issues with regular admin + * login. For example, if password is lost and can't be restored. + */ + public static final ConfigKey WEB_SERVICE_ACCOUNT_TOKEN = new StringConfigKey( + "web.serviceAccountToken", + List.of(KeyType.CONFIG)); + /** * Cross-origin resource sharing origin header value. */ diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java deleted file mode 100644 index 2c541e2aa..000000000 --- a/src/main/java/org/traccar/database/LoginService.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.database; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.User; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.annotation.Nullable; -import javax.inject.Inject; - -public class LoginService { - - private final Storage storage; - private final LdapProvider ldapProvider; - - private final boolean forceLdap; - - @Inject - public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { - this.storage = storage; - this.ldapProvider = ldapProvider; - forceLdap = config.getBoolean(Keys.LDAP_FORCE); - } - - public User login(String token) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("token", "token", token))); - if (user != null) { - checkUserEnabled(user); - } - return user; - } - - public User login(String email, String password) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.All(), - new Condition.Or( - new Condition.Equals("email", "email", email.trim()), - new Condition.Equals("login", "email")))); - if (user != null) { - if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) - || !forceLdap && user.isPasswordValid(password)) { - checkUserEnabled(user); - return user; - } - } else { - if (ldapProvider != null && ldapProvider.login(email, password)) { - user = ldapProvider.getUser(email); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - checkUserEnabled(user); - return user; - } - } - return null; - } - - private void checkUserEnabled(User user) throws SecurityException { - if (user == null) { - throw new SecurityException("Unknown account"); - } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } - } - -} -- cgit v1.2.3 From cc9eca495f93b8ffaee0fe5b10b62f1f3dfbf945 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 07:22:14 -0700 Subject: Return storage info --- .../java/org/traccar/api/resource/ServerResource.java | 6 ++++++ src/main/java/org/traccar/helper/Log.java | 18 ++++++++++++++++++ src/main/java/org/traccar/model/Server.java | 12 ++++++++++++ 3 files changed, 36 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index b66f5a931..2ef99c578 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -18,8 +18,10 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.geocoder.Geocoder; +import org.traccar.helper.Log; import org.traccar.helper.LogAction; import org.traccar.model.Server; +import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -60,6 +62,10 @@ public class ServerResource extends BaseResource { public Server get() throws StorageException { Server server = storage.getObject(Server.class, new Request(new Columns.All())); server.setEmailEnabled(mailManager.getEmailEnabled()); + User user = permissionsService.getUser(getUserId()); + if (user != null && user.getAdministrator()) { + server.setStorageSpace(Log.getStorageSpace()); + } return server; } diff --git a/src/main/java/org/traccar/helper/Log.java b/src/main/java/org/traccar/helper/Log.java index 8c67f9ddc..e1b201f9f 100644 --- a/src/main/java/org/traccar/helper/Log.java +++ b/src/main/java/org/traccar/helper/Log.java @@ -28,6 +28,10 @@ import java.io.StringWriter; import java.io.Writer; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.FileStore; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.ConsoleHandler; @@ -269,4 +273,18 @@ public final class Log { return s.toString(); } + public static long[] getStorageSpace() { + long usable = 0; + long total = 0; + for (Path root : FileSystems.getDefault().getRootDirectories()) { + try { + FileStore store = Files.getFileStore(root); + usable += store.getUsableSpace(); + total += store.getTotalSpace(); + } catch (IOException ignored) { + } + } + return new long[]{usable, total}; + } + } diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index ee7f7069a..648be2991 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -214,4 +214,16 @@ public class Server extends ExtendedModel implements UserRestrictions { return emailEnabled; } + private long[] storageSpace; + + @QueryIgnore + public long[] getStorageSpace() { + return storageSpace; + } + + @QueryIgnore + public void setStorageSpace(long[] storageSpace) { + this.storageSpace = storageSpace; + } + } -- cgit v1.2.3 From 1271b2e7a772c8458b567d7f424d5a38365b5d75 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 08:35:59 -0700 Subject: Login as another user --- .../java/org/traccar/api/resource/SessionResource.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 91052fc6b..8eabdc63c 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -22,6 +22,9 @@ import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; import javax.inject.Inject; @@ -33,6 +36,7 @@ import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; @@ -107,6 +111,17 @@ public class SessionResource extends BaseResource { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } + @Path("{id}") + @GET + public User get(@PathParam("id") long userId) throws StorageException { + permissionsService.checkAdmin(getUserId()); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", userId))); + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + @PermitAll @POST public User add( -- cgit v1.2.3 From 6a608f109ab587803092374591d1ec22e8f40fb7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 08:43:50 -0700 Subject: Support token API authentication --- .../java/org/traccar/api/security/SecurityRequestFilter.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index eaf5b28c4..ada7bf997 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -43,6 +43,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; public static final String BASIC_REALM = "Basic realm=\"api\""; + public static final String BEARER_PREFIX = "Bearer "; public static final String X_REQUESTED_WITH = "X-Requested-With"; public static final String XML_HTTP_REQUEST = "XMLHttpRequest"; @@ -82,8 +83,13 @@ public class SecurityRequestFilter implements ContainerRequestFilter { if (authHeader != null) { try { - String[] auth = decodeBasicAuth(authHeader); - User user = loginService.login(auth[0], auth[1]); + User user; + if (authHeader.startsWith(BEARER_PREFIX)) { + user = loginService.login(authHeader.substring(BEARER_PREFIX.length())); + } else { + String[] auth = decodeBasicAuth(authHeader); + user = loginService.login(auth[0], auth[1]); + } if (user != null) { statisticsManager.registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); -- cgit v1.2.3 From d24edbc439a96b38442be1fbbfaccf65f0dd1923 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 08:58:34 -0700 Subject: Fix accumulator update --- src/main/java/org/traccar/MainEventHandler.java | 2 -- src/main/java/org/traccar/api/resource/DeviceResource.java | 12 +++++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 965421d2f..06791c540 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -89,8 +89,6 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { new Condition.Equals("id", "id"))); cacheManager.updatePosition(position); - cacheManager.getObject(Device.class, position.getDeviceId()).setPositionId(position.getId()); - connectionManager.updatePosition(position); } } catch (StorageException error) { diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 74e133f44..ff682d1d1 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -21,6 +21,7 @@ import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -48,6 +49,9 @@ public class DeviceResource extends BaseObjectResource { @Inject private CacheManager cacheManager; + @Inject + private ConnectionManager connectionManager; + public DeviceResource() { super(Device.class); } @@ -125,7 +129,13 @@ public class DeviceResource extends BaseObjectResource { new Columns.Include("positionId"), new Condition.Equals("id", "id"))); - cacheManager.updatePosition(position); + try { + cacheManager.addDevice(position.getDeviceId()); + cacheManager.updatePosition(position); + connectionManager.updatePosition(position); + } finally { + cacheManager.removeDevice(position.getDeviceId()); + } } else { throw new IllegalArgumentException(); } -- cgit v1.2.3 From bf504bdda752dfbde1a81ece03805d14a4bd117c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Jun 2022 16:29:25 -0700 Subject: Decode ST300UEX serial data --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 4 +++- src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java | 4 ++++ src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 44ba1da38..67a82a688 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -375,7 +375,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } } else if (attribute.startsWith("GTSL")) { position.set(Position.KEY_DRIVER_UNIQUE_ID, attribute.split("\\|")[4]); - } else { + } else if (attribute.contains("=")) { String[] pair = attribute.split("="); if (pair.length >= 2) { String value = pair[1].trim(); @@ -398,6 +398,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { break; } } + } else { + position.set("serial", attribute); } remaining -= attribute.length() + 1; } diff --git a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java index 96fed314c..6d0351a8e 100644 --- a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java @@ -10,6 +10,10 @@ public class SuntechFrameDecoderTest extends ProtocolTest { var decoder = inject(new SuntechFrameDecoder()); + verifyFrame( + binary("53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b30"), + decoder.decode(null, null, binary("53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b300d"))); + verifyFrame( binary("81004e05200013383fffff3401000301130a0512080400000000000000000000000047f9d5846a06810072225214010100020300a8002604c1000004b000000470000025a100000000000025c4000000a6"), decoder.decode(null, null, binary("81004e05200013383fffff3401000301130a0512080400000000000000000000000047f9d5846a06810072225214010100020300a8002604c1000004b000000470000025a100000000000025c4000000a6"))); diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 7fed55454..71f71ce99 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -92,6 +92,13 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, buffer( "BSA;0820012345;001FFF;82;1.0.0;1;20191203;17:00:51;+32.691615;-117.297160;1;-55;68:11:6A:FD:1A:A7;6AA5;1DE8")); + verifyAttributes(decoder, binary( + "53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b30")); + + verifyAttribute(decoder, buffer( + "ST300UEX;100850000;01;010;20081017;07:41:56;2F100;+37.478519;+126.886819;000.012;000.00;9;1;0;15.30;001100;25;Welcome to Suntech World!;12;0;4.5;1"), + "serial", "Welcome to Suntech World!"); + verifyAttribute(decoder, buffer( "ST300UEX;511331307;45;311;20210420;12:41:01;12361;-01.280825;-047.931773;000.000;000.00;16;1;0;12.54;000000;23;GTSL|6|1|0|9255143|2|;6F;000276;0.0;1;00000000000000;0"), Position.KEY_DRIVER_UNIQUE_ID, "9255143"); -- cgit v1.2.3 From c60743cfab4e31214207da5dab44fc4426d53764 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Jun 2022 08:06:17 -0700 Subject: Check if resources loaded --- src/main/java/org/traccar/web/WebServer.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 6c8a798b4..68eee78e7 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -40,6 +40,8 @@ import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerI import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; import org.traccar.api.CorsResponseFilter; import org.traccar.api.DateParameterConverterProvider; @@ -67,6 +69,8 @@ import java.util.EnumSet; public class WebServer implements LifecycleObject { + private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); + private final Injector injector; private final Config config; private final Server server; @@ -180,6 +184,9 @@ public class WebServer implements LifecycleObject { CorsResponseFilter.class, ResourceErrorHandler.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); + if (resourceConfig.getClasses().stream().filter(ServerResource.class::equals).findAny().isEmpty()) { + LOGGER.warn("Failed to load API resources"); + } servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } -- cgit v1.2.3 From 5a732a26c85785a9b801583f2fff0ce47314aa03 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 07:54:39 -0700 Subject: Add throttling filter --- build.gradle | 1 + src/main/java/org/traccar/config/Keys.java | 7 +++ .../java/org/traccar/web/ThrottlingFilter.java | 53 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebModule.java | 1 + 4 files changed, 62 insertions(+) create mode 100644 src/main/java/org/traccar/web/ThrottlingFilter.java (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 8c196043a..8ce916432 100644 --- a/build.gradle +++ b/build.gradle @@ -54,6 +54,7 @@ dependencies { implementation "org.glassfish:javax.json:1.1.4" implementation "org.eclipse.jetty:jetty-server:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlet:$jettyVersion" + implementation "org.eclipse.jetty:jetty-servlets:$jettyVersion" implementation "org.eclipse.jetty:jetty-webapp:$jettyVersion" implementation "org.eclipse.jetty:jetty-jndi:$jettyVersion" implementation "org.eclipse.jetty:jetty-proxy:$jettyVersion" diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 3f52fbd96..8e11b4013 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -628,6 +628,13 @@ public final class Keys { "web.port", List.of(KeyType.CONFIG)); + /** + * Maximum API requests per second. Above this limit requests and delayed and throttled. + */ + public static final ConfigKey WEB_MAX_REQUESTS_PER_SECOND = new IntegerConfigKey( + "web.maxRequestsPerSec", + List.of(KeyType.CONFIG)); + /** * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based * interface doesn't require this. diff --git a/src/main/java/org/traccar/web/ThrottlingFilter.java b/src/main/java/org/traccar/web/ThrottlingFilter.java new file mode 100644 index 000000000..054af652f --- /dev/null +++ b/src/main/java/org/traccar/web/ThrottlingFilter.java @@ -0,0 +1,53 @@ +/* + * 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.web; + +import org.eclipse.jetty.servlets.DoSFilter; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +@Singleton +public class ThrottlingFilter extends DoSFilter { + + @Inject + private Config config; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + super.init(filterConfig); + if (config.hasKey(Keys.WEB_MAX_REQUESTS_PER_SECOND)) { + setMaxRequestsPerSec(config.getInteger(Keys.WEB_MAX_REQUESTS_PER_SECOND)); + } + } + + @Override + protected String extractUserId(ServletRequest request) { + HttpSession session = ((HttpServletRequest) request).getSession(false); + if (session != null) { + var userId = session.getAttribute("userId"); + return userId != null ? userId.toString() : null; + } + return null; + } +} diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java index 6c133ff74..0722c5d1e 100644 --- a/src/main/java/org/traccar/web/WebModule.java +++ b/src/main/java/org/traccar/web/WebModule.java @@ -23,6 +23,7 @@ public class WebModule extends ServletModule { @Override protected void configureServlets() { + filter("/api/*").through(ThrottlingFilter.class); filter("/api/media/*").through(MediaFilter.class); serve("/api/socket").with(AsyncSocketServlet.class); } -- cgit v1.2.3 From c53d98c668af9c79767e22964f05c7bf7dc866f2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 13:33:35 -0700 Subject: Integrate broadcast service --- src/main/java/org/traccar/MainEventHandler.java | 8 +- src/main/java/org/traccar/MainModule.java | 7 +- .../java/org/traccar/api/BaseObjectResource.java | 8 +- .../org/traccar/api/resource/DeviceResource.java | 8 +- .../traccar/api/resource/PermissionsResource.java | 22 ++- .../org/traccar/broadcast/BroadcastInterface.java | 41 +++++ .../org/traccar/broadcast/BroadcastMessage.java | 43 +++++- .../org/traccar/broadcast/BroadcastService.java | 80 +--------- .../java/org/traccar/broadcast/DeviceStatus.java | 52 ------- .../broadcast/MulticastBroadcastService.java | 170 +++++++++++++++++++++ .../traccar/broadcast/NullBroadcastService.java | 31 ++++ src/main/java/org/traccar/model/Permission.java | 8 +- .../org/traccar/notificators/NotificatorWeb.java | 8 +- .../org/traccar/session/ConnectionManager.java | 13 +- .../org/traccar/session/cache/CacheManager.java | 37 +++-- 15 files changed, 374 insertions(+), 162 deletions(-) create mode 100644 src/main/java/org/traccar/broadcast/BroadcastInterface.java delete mode 100644 src/main/java/org/traccar/broadcast/DeviceStatus.java create mode 100644 src/main/java/org/traccar/broadcast/MulticastBroadcastService.java create mode 100644 src/main/java/org/traccar/broadcast/NullBroadcastService.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 06791c540..0a8c69b54 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; @@ -56,15 +57,17 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Storage storage; private final ConnectionManager connectionManager; private final StatisticsManager statisticsManager; + private final BroadcastService broadcastService; @Inject public MainEventHandler( - Config config, CacheManager cacheManager, Storage storage, - ConnectionManager connectionManager, StatisticsManager statisticsManager) { + Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager, + StatisticsManager statisticsManager, BroadcastService broadcastService) { this.cacheManager = cacheManager; this.storage = storage; this.connectionManager = connectionManager; this.statisticsManager = statisticsManager; + this.broadcastService = broadcastService; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); @@ -90,6 +93,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { cacheManager.updatePosition(position); connectionManager.updatePosition(position); + broadcastService.updatePosition(position); } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 5a5675859..f60d41d62 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -29,6 +29,8 @@ import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.log.NullLogChute; import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; +import org.traccar.broadcast.MulticastBroadcastService; +import org.traccar.broadcast.NullBroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; @@ -278,13 +280,14 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static BroadcastService provideBroadcastService( Config config, ObjectMapper objectMapper) throws IOException { if (config.hasKey(Keys.BROADCAST_ADDRESS)) { - return new BroadcastService(config, objectMapper); + return new MulticastBroadcastService(config, objectMapper); } - return null; + return new NullBroadcastService(); } @Provides diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 35ff04bf3..403021c6c 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -16,6 +16,7 @@ */ package org.traccar.api; +import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Group; @@ -41,6 +42,9 @@ public abstract class BaseObjectResource extends BaseResour @Inject private CacheManager cacheManager; + @Inject + private BroadcastService broadcastService; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -67,7 +71,8 @@ public abstract class BaseObjectResource extends BaseResour entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); - cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); + cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); + broadcastService.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); @@ -94,6 +99,7 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); cacheManager.updateOrInvalidate(entity); + broadcastService.invalidateObject(entity.getClass(), entity.getId()); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index ff682d1d1..2b673a108 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -16,6 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseObjectResource; +import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; @@ -37,6 +38,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -52,6 +54,9 @@ public class DeviceResource extends BaseObjectResource { @Inject private ConnectionManager connectionManager; + @Inject + private BroadcastService broadcastService; + public DeviceResource() { super(Device.class); } @@ -105,7 +110,7 @@ public class DeviceResource extends BaseObjectResource { @Path("{id}/accumulators") @PUT - public Response updateAccumulators(DeviceAccumulators entity) throws StorageException { + public Response updateAccumulators(DeviceAccumulators entity) throws StorageException, IOException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkManager(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); @@ -133,6 +138,7 @@ public class DeviceResource extends BaseObjectResource { cacheManager.addDevice(position.getDeviceId()); cacheManager.updatePosition(position); connectionManager.updatePosition(position); + broadcastService.updatePosition(position); } finally { cacheManager.removeDevice(position.getDeviceId()); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 7174a3eff..5ca865c31 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.Permission; import org.traccar.model.UserRestrictions; @@ -45,6 +46,9 @@ public class PermissionsResource extends BaseResource { @Inject private CacheManager cacheManager; + @Inject + private BroadcastService broadcastService; + private void checkPermission(Permission permission) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -71,9 +75,14 @@ public class PermissionsResource extends BaseResource { Permission permission = new Permission(entity); checkPermission(permission); storage.addPermission(permission); - cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + cacheManager.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), + broadcastService.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); + LogAction.link(getUserId(), + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } return Response.noContent().build(); @@ -93,9 +102,14 @@ public class PermissionsResource extends BaseResource { Permission permission = new Permission(entity); checkPermission(permission); storage.removePermission(permission); - cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + cacheManager.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); + broadcastService.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), + LogAction.unlink(getUserId(), + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } return Response.noContent().build(); diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java new file mode 100644 index 000000000..d5b49f213 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -0,0 +1,41 @@ +/* + * 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.broadcast; + +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Position; + +public interface BroadcastInterface { + + default void updateDevice(Device device) { + } + + default void updatePosition(Position position) { + } + + default void updateEvent(long userId, Event event) { + } + + default void invalidateObject(Class clazz, long id) { + } + + default void invalidatePermission( + Class clazz1, long id1, + Class clazz2, long id2) { + } +} diff --git a/src/main/java/org/traccar/broadcast/BroadcastMessage.java b/src/main/java/org/traccar/broadcast/BroadcastMessage.java index 6b103f373..3e22be7e0 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastMessage.java +++ b/src/main/java/org/traccar/broadcast/BroadcastMessage.java @@ -15,18 +15,22 @@ */ package org.traccar.broadcast; +import org.traccar.model.Device; +import org.traccar.model.Event; import org.traccar.model.Position; +import java.util.Map; + public class BroadcastMessage { - private DeviceStatus deviceStatus; + private Device device; - public DeviceStatus getDeviceStatus() { - return deviceStatus; + public Device getDevice() { + return device; } - public void setDeviceStatus(DeviceStatus deviceStatus) { - this.deviceStatus = deviceStatus; + public void setDevice(Device device) { + this.device = device; } private Position position; @@ -39,4 +43,33 @@ public class BroadcastMessage { this.position = position; } + private Long userId; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + + private Map changes; + + public Map getChanges() { + return changes; + } + + public void setChanges(Map changes) { + this.changes = changes; + } } diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java index 26e38400b..8a2e4bafc 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastService.java +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -15,84 +15,8 @@ */ package org.traccar.broadcast; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; -import org.traccar.config.Config; -import org.traccar.config.Keys; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.MulticastSocket; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class BroadcastService implements LifecycleObject { - - private static final Logger LOGGER = LoggerFactory.getLogger(BroadcastService.class); - - private final ObjectMapper objectMapper; - - private final InetAddress address; - private final int port; - - private DatagramSocket publisherSocket; - - private final ExecutorService service = Executors.newSingleThreadExecutor(); - private final byte[] receiverBuffer = new byte[4096]; - - public BroadcastService(Config config, ObjectMapper objectMapper) throws IOException { - this.objectMapper = objectMapper; - address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); - port = config.getInteger(Keys.BROADCAST_PORT); - } - - public void sendMessage(BroadcastMessage message) throws IOException { - byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); - DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); - publisherSocket.send(packet); - } - - private void handleMessage(BroadcastMessage message) { - if (message.getDeviceStatus() != null) { - LOGGER.info("Broadcast received device {}", message.getDeviceStatus().getDeviceId()); - } else if (message.getPosition() != null) { - LOGGER.info("Broadcast received position {}", message.getPosition().getDeviceId()); - } - } - - @Override - public void start() throws IOException { - service.submit(receiver); - publisherSocket = new DatagramSocket(); - } - - @Override - public void stop() { - publisherSocket.close(); - service.shutdown(); - } - - private final Runnable receiver = new Runnable() { - @Override - public void run() { - try (MulticastSocket socket = new MulticastSocket(port)) { - socket.joinGroup(address); - while (!service.isShutdown()) { - DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); - socket.receive(packet); - String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); - handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); - } - socket.leaveGroup(address); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }; +public interface BroadcastService extends LifecycleObject, BroadcastInterface { + void registerListener(BroadcastInterface listener); } diff --git a/src/main/java/org/traccar/broadcast/DeviceStatus.java b/src/main/java/org/traccar/broadcast/DeviceStatus.java deleted file mode 100644 index 4f0143319..000000000 --- a/src/main/java/org/traccar/broadcast/DeviceStatus.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.broadcast; - -import java.util.Date; - -public class DeviceStatus { - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - - private String status; - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - private Date lastUpdate; - - public Date getLastUpdate() { - return this.lastUpdate; - } - - public void setLastUpdate(Date lastUpdate) { - this.lastUpdate = lastUpdate; - } - -} diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java new file mode 100644 index 000000000..0525fa742 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -0,0 +1,170 @@ +/* + * 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.broadcast; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Permission; +import org.traccar.model.Position; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class MulticastBroadcastService implements BroadcastService { + + private static final Logger LOGGER = LoggerFactory.getLogger(MulticastBroadcastService.class); + + private final ObjectMapper objectMapper; + + private final InetAddress address; + private final int port; + + private DatagramSocket publisherSocket; + + private final ExecutorService service = Executors.newSingleThreadExecutor(); + private final byte[] receiverBuffer = new byte[4096]; + + private final Set listeners = new HashSet<>(); + + public MulticastBroadcastService(Config config, ObjectMapper objectMapper) throws IOException { + this.objectMapper = objectMapper; + address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); + port = config.getInteger(Keys.BROADCAST_PORT); + } + + @Override + public void registerListener(BroadcastInterface listener) { + listeners.add(listener); + } + + @Override + public void updateDevice(Device device) { + BroadcastMessage message = new BroadcastMessage(); + message.setDevice(device); + sendMessage(message); + } + + @Override + public void updatePosition(Position position) { + BroadcastMessage message = new BroadcastMessage(); + message.setPosition(position); + sendMessage(message); + } + + @Override + public void updateEvent(long userId, Event event) { + BroadcastMessage message = new BroadcastMessage(); + message.setUserId(userId); + message.setEvent(event); + sendMessage(message); + } + + @Override + public void invalidateObject(Class clazz, long id) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz), id)); + sendMessage(message); + } + + @Override + public void invalidatePermission( + Class clazz1, long id1, + Class clazz2, long id2) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz1), id1, Permission.getKey(clazz2), id2)); + sendMessage(message); + } + + private void sendMessage(BroadcastMessage message) { + try { + byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); + publisherSocket.send(packet); + } catch (IOException e) { + LOGGER.warn("Broadcast failed", e); + } + } + + private void handleMessage(BroadcastMessage message) { + if (message.getDevice() != null) { + listeners.forEach(listener -> listener.updateDevice(message.getDevice())); + } else if (message.getPosition() != null) { + listeners.forEach(listener -> listener.updatePosition(message.getPosition())); + } else if (message.getUserId() != null && message.getEvent() != null) { + listeners.forEach(listener -> listener.updateEvent(message.getUserId(), message.getEvent())); + } else if (message.getChanges() != null) { + var iterator = message.getChanges().entrySet().iterator(); + if (iterator.hasNext()) { + var first = iterator.next(); + if (iterator.hasNext()) { + var second = iterator.next(); + listeners.forEach(listener -> listener.invalidatePermission( + Permission.getKeyClass(first.getKey()), first.getValue(), + Permission.getKeyClass(second.getKey()), second.getValue())); + } else { + listeners.forEach(listener -> listener.invalidateObject( + Permission.getKeyClass(first.getKey()), first.getValue())); + } + } + } + } + + @Override + public void start() throws IOException { + service.submit(receiver); + publisherSocket = new DatagramSocket(); + } + + @Override + public void stop() { + publisherSocket.close(); + service.shutdown(); + } + + private final Runnable receiver = new Runnable() { + @SuppressWarnings("deprecation") + @Override + public void run() { + try (MulticastSocket socket = new MulticastSocket(port)) { + socket.joinGroup(address); + while (!service.isShutdown()) { + DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); + socket.receive(packet); + String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + } + socket.leaveGroup(address); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }; +} diff --git a/src/main/java/org/traccar/broadcast/NullBroadcastService.java b/src/main/java/org/traccar/broadcast/NullBroadcastService.java new file mode 100644 index 000000000..3f41299db --- /dev/null +++ b/src/main/java/org/traccar/broadcast/NullBroadcastService.java @@ -0,0 +1,31 @@ +/* + * 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.broadcast; + +public class NullBroadcastService implements BroadcastService { + + @Override + public void registerListener(BroadcastInterface listener) { + } + + @Override + public void start() throws Exception { + } + + @Override + public void stop() throws Exception { + } +} diff --git a/src/main/java/org/traccar/model/Permission.java b/src/main/java/org/traccar/model/Permission.java index 41dfa43e4..0b2f0584f 100644 --- a/src/main/java/org/traccar/model/Permission.java +++ b/src/main/java/org/traccar/model/Permission.java @@ -54,10 +54,10 @@ public class Permission { this.data = data; var iterator = data.entrySet().iterator(); var owner = iterator.next(); - ownerClass = CLASSES.get(owner.getKey().substring(0, owner.getKey().length() - 2)); + ownerClass = getKeyClass(owner.getKey()); ownerId = owner.getValue(); var property = iterator.next(); - propertyClass = CLASSES.get(property.getKey().substring(0, property.getKey().length() - 2)); + propertyClass = getKeyClass(property.getKey()); propertyId = property.getValue(); } @@ -73,6 +73,10 @@ public class Permission { data.put(getKey(propertyClass), propertyId); } + public static Class getKeyClass(String key) { + return CLASSES.get(key.substring(0, key.length() - 2)); + } + public static String getKey(Class clazz) { return Introspector.decapitalize(clazz.getSimpleName()) + "Id"; } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 3d899584d..efbbf24cc 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -16,6 +16,7 @@ */ package org.traccar.notificators; +import org.traccar.broadcast.BroadcastService; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; @@ -27,11 +28,15 @@ import javax.inject.Inject; public final class NotificatorWeb implements Notificator { private final ConnectionManager connectionManager; + private final BroadcastService broadcastService; private final NotificationFormatter notificationFormatter; @Inject - public NotificatorWeb(ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { + public NotificatorWeb( + ConnectionManager connectionManager, BroadcastService broadcastService, + NotificationFormatter notificationFormatter) { this.connectionManager = connectionManager; + this.broadcastService = broadcastService; this.notificationFormatter = notificationFormatter; } @@ -52,6 +57,7 @@ public final class NotificatorWeb implements Notificator { copy.set("message", message.getBody()); connectionManager.updateEvent(user.getId(), copy); + broadcastService.updateEvent(user.getId(), copy); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index fe6521d18..74427c08b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -22,6 +22,8 @@ import io.netty.util.Timer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Protocol; +import org.traccar.broadcast.BroadcastInterface; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.NotificationManager; @@ -52,7 +54,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @Singleton -public class ConnectionManager { +public class ConnectionManager implements BroadcastInterface { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); @@ -70,6 +72,7 @@ public class ConnectionManager { private final Storage storage; private final NotificationManager notificationManager; private final Timer timer; + private final BroadcastService broadcastService; private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); @@ -77,15 +80,17 @@ public class ConnectionManager { @Inject public ConnectionManager( Injector injector, Config config, CacheManager cacheManager, Storage storage, - NotificationManager notificationManager, Timer timer) { + NotificationManager notificationManager, Timer timer, BroadcastService broadcastService) { this.injector = injector; this.config = config; this.cacheManager = cacheManager; this.storage = storage; this.notificationManager = notificationManager; this.timer = timer; + this.broadcastService = broadcastService; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); + broadcastService.registerListener(this); } public DeviceSession getDeviceSession(long deviceId) { @@ -270,6 +275,7 @@ public class ConnectionManager { } updateDevice(device); + broadcastService.updateDevice(device); } public DeviceState getDeviceState(long deviceId) { @@ -306,6 +312,7 @@ public class ConnectionManager { } } + @Override public synchronized void updateDevice(Device device) { for (User user : cacheManager.getDeviceObjects(device.getId(), User.class)) { if (listeners.containsKey(user.getId())) { @@ -316,6 +323,7 @@ public class ConnectionManager { } } + @Override public synchronized void updatePosition(Position position) { long deviceId = position.getDeviceId(); for (User user : cacheManager.getDeviceObjects(deviceId, User.class)) { @@ -327,6 +335,7 @@ public class ConnectionManager { } } + @Override public synchronized void updateEvent(long userId, Event event) { if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index abc8ca4c9..d2ada7d43 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,8 @@ */ package org.traccar.session.cache; +import org.traccar.broadcast.BroadcastInterface; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; @@ -49,7 +51,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; @Singleton -public class CacheManager { +public class CacheManager implements BroadcastInterface { private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); @@ -68,9 +70,10 @@ public class CacheManager { private final Map> notificationUsers = new HashMap<>(); @Inject - public CacheManager(Config config, Storage storage) throws StorageException { + public CacheManager(Config config, Storage storage, BroadcastService broadcastService) throws StorageException { this.config = config; this.storage = storage; + broadcastService.registerListener(this); invalidateServer(); invalidateUsers(); } @@ -179,13 +182,18 @@ public class CacheManager { } } - public void updateOrInvalidate(Class clazz, long id) throws StorageException { - var object = storage.getObject(clazz, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); - if (object != null) { - updateOrInvalidate(object); - } else { - invalidate(clazz, id); + @Override + public void invalidateObject(Class clazz, long id) { + try { + var object = storage.getObject(clazz, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); + if (object != null) { + updateOrInvalidate(object); + } else { + invalidate(clazz, id); + } + } catch (StorageException e) { + throw new RuntimeException(e); } } @@ -219,10 +227,15 @@ public class CacheManager { invalidate(new CacheKey(clazz, id)); } - public void invalidate( + @Override + public void invalidatePermission( Class clazz1, long id1, - Class clazz2, long id2) throws StorageException { - invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); + Class clazz2, long id2) { + try { + invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); + } catch (StorageException e) { + throw new RuntimeException(e); + } } private void invalidateServer() throws StorageException { -- cgit v1.2.3 From 2fcffc5b55f59310d289a21d1ebc2ee6bf15bcd5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 14:17:00 -0700 Subject: Fix connection users issue --- src/main/java/org/traccar/MainEventHandler.java | 4 +- src/main/java/org/traccar/api/AsyncSocket.java | 7 +-- .../org/traccar/api/resource/DeviceResource.java | 4 +- .../org/traccar/broadcast/BroadcastInterface.java | 6 +- .../broadcast/MulticastBroadcastService.java | 12 ++-- .../handler/events/GeofenceEventHandler.java | 2 +- .../org/traccar/notificators/NotificatorWeb.java | 4 +- .../org/traccar/session/ConnectionManager.java | 66 +++++++++++++++------- 8 files changed, 65 insertions(+), 40 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 0a8c69b54..e2cad15c6 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -92,8 +92,8 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { new Condition.Equals("id", "id"))); cacheManager.updatePosition(position); - connectionManager.updatePosition(position); - broadcastService.updatePosition(position); + connectionManager.updatePosition(true, position); + broadcastService.updatePosition(true, position); } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index 40aa68e88..5fc4b4412 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -58,15 +58,14 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U public void onWebSocketConnect(Session session) { super.onWebSocketConnect(session); - Map> data = new HashMap<>(); try { + Map> data = new HashMap<>(); data.put(KEY_POSITIONS, PositionUtil.getLatestPositions(storage, userId)); + sendData(data); + connectionManager.addListener(userId, this); } catch (StorageException e) { throw new RuntimeException(e); } - sendData(data); - - connectionManager.addListener(userId, this); } @Override diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 2b673a108..e205f2d28 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -137,8 +137,8 @@ public class DeviceResource extends BaseObjectResource { try { cacheManager.addDevice(position.getDeviceId()); cacheManager.updatePosition(position); - connectionManager.updatePosition(position); - broadcastService.updatePosition(position); + connectionManager.updatePosition(true, position); + broadcastService.updatePosition(true, position); } finally { cacheManager.removeDevice(position.getDeviceId()); } diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java index d5b49f213..69e610dc6 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastInterface.java +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -22,13 +22,13 @@ import org.traccar.model.Position; public interface BroadcastInterface { - default void updateDevice(Device device) { + default void updateDevice(boolean local, Device device) { } - default void updatePosition(Position position) { + default void updatePosition(boolean local, Position position) { } - default void updateEvent(long userId, Event event) { + default void updateEvent(boolean local, long userId, Event event) { } default void invalidateObject(Class clazz, long id) { diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 0525fa742..ac0fcbd86 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -66,21 +66,21 @@ public class MulticastBroadcastService implements BroadcastService { } @Override - public void updateDevice(Device device) { + public void updateDevice(boolean local, Device device) { BroadcastMessage message = new BroadcastMessage(); message.setDevice(device); sendMessage(message); } @Override - public void updatePosition(Position position) { + public void updatePosition(boolean local, Position position) { BroadcastMessage message = new BroadcastMessage(); message.setPosition(position); sendMessage(message); } @Override - public void updateEvent(long userId, Event event) { + public void updateEvent(boolean local, long userId, Event event) { BroadcastMessage message = new BroadcastMessage(); message.setUserId(userId); message.setEvent(event); @@ -115,11 +115,11 @@ public class MulticastBroadcastService implements BroadcastService { private void handleMessage(BroadcastMessage message) { if (message.getDevice() != null) { - listeners.forEach(listener -> listener.updateDevice(message.getDevice())); + listeners.forEach(listener -> listener.updateDevice(false, message.getDevice())); } else if (message.getPosition() != null) { - listeners.forEach(listener -> listener.updatePosition(message.getPosition())); + listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); } else if (message.getUserId() != null && message.getEvent() != null) { - listeners.forEach(listener -> listener.updateEvent(message.getUserId(), message.getEvent())); + listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); } else if (message.getChanges() != null) { var iterator = message.getChanges().entrySet().iterator(); if (iterator.hasNext()) { diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 0a924cfc3..ca3fc3f89 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -68,7 +68,7 @@ public class GeofenceEventHandler extends BaseEventHandler { device.setGeofenceIds(currentGeofences); if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) { - connectionManager.updateDevice(device); + connectionManager.updateDevice(true, device); } Map events = new HashMap<>(); diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index efbbf24cc..061018ba9 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -56,8 +56,8 @@ public final class NotificatorWeb implements Notificator { var message = notificationFormatter.formatMessage(user, event, position, "short"); copy.set("message", message.getBody()); - connectionManager.updateEvent(user.getId(), copy); - broadcastService.updateEvent(user.getId(), copy); + connectionManager.updateEvent(true, user.getId(), copy); + broadcastService.updateEvent(true, user.getId(), copy); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 74427c08b..0e0ea1eb8 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -30,6 +30,7 @@ import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.helper.model.AttributeUtil; +import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; @@ -45,6 +46,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -52,6 +54,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; @Singleton public class ConnectionManager implements BroadcastInterface { @@ -74,7 +77,10 @@ public class ConnectionManager implements BroadcastInterface { private final Timer timer; private final BroadcastService broadcastService; - private final Map> listeners = new ConcurrentHashMap<>(); + private final Map> listeners = new HashMap<>(); + private final Map> userDevices = new HashMap<>(); + private final Map> deviceUsers = new HashMap<>(); + private final Map timeouts = new ConcurrentHashMap<>(); @Inject @@ -197,6 +203,10 @@ public class ConnectionManager implements BroadcastInterface { public void deviceUnknown(long deviceId) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + removeDeviceSession(deviceId); + } + + private void removeDeviceSession(long deviceId) { DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); if (deviceSession != null) { cacheManager.removeDevice(deviceId); @@ -274,8 +284,8 @@ public class ConnectionManager implements BroadcastInterface { LOGGER.warn("Update device status error", e); } - updateDevice(device); - broadcastService.updateDevice(device); + updateDevice(true, device); + broadcastService.updateDevice(true, device); } public DeviceState getDeviceState(long deviceId) { @@ -313,10 +323,14 @@ public class ConnectionManager implements BroadcastInterface { } @Override - public synchronized void updateDevice(Device device) { - for (User user : cacheManager.getDeviceObjects(device.getId(), User.class)) { - if (listeners.containsKey(user.getId())) { - for (UpdateListener listener : listeners.get(user.getId())) { + public synchronized void updateDevice(boolean local, Device device) { + if (!local && Device.STATUS_ONLINE.equals(device.getStatus())) { + timeouts.remove(device.getId()); + removeDeviceSession(device.getId()); + } + for (long userId : deviceUsers.getOrDefault(device.getId(), Collections.emptySet())) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { listener.onUpdateDevice(device); } } @@ -324,11 +338,10 @@ public class ConnectionManager implements BroadcastInterface { } @Override - public synchronized void updatePosition(Position position) { - long deviceId = position.getDeviceId(); - for (User user : cacheManager.getDeviceObjects(deviceId, User.class)) { - if (listeners.containsKey(user.getId())) { - for (UpdateListener listener : listeners.get(user.getId())) { + public synchronized void updatePosition(boolean local, Position position) { + for (long userId : deviceUsers.getOrDefault(position.getDeviceId(), Collections.emptySet())) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { listener.onUpdatePosition(position); } } @@ -336,7 +349,7 @@ public class ConnectionManager implements BroadcastInterface { } @Override - public synchronized void updateEvent(long userId, Event event) { + public synchronized void updateEvent(boolean local, long userId, Event event) { if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { listener.onUpdateEvent(event); @@ -351,18 +364,31 @@ public class ConnectionManager implements BroadcastInterface { void onUpdateEvent(Event event); } - public synchronized void addListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); + public synchronized void addListener(long userId, UpdateListener listener) throws StorageException { + var set = listeners.get(userId); + if (set == null) { + set = new HashSet<>(); + listeners.put(userId, set); + + var devices = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))); + userDevices.put(userId, devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet())); + devices.forEach(device -> deviceUsers.computeIfAbsent(device.getId(), id -> new HashSet<>()).add(userId)); } - listeners.get(userId).add(listener); + set.add(listener); } public synchronized void removeListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); + var set = listeners.get(userId); + set.remove(listener); + if (set.isEmpty()) { + listeners.remove(userId); + + userDevices.remove(userId).forEach(deviceId -> deviceUsers.computeIfPresent(deviceId, (x, userIds) -> { + userIds.remove(userId); + return userIds.isEmpty() ? null : userIds; + })); } - listeners.get(userId).remove(listener); } } -- cgit v1.2.3 From bf0173eb4bac4ab86b43f101eb013051bfc40817 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 14:24:08 -0700 Subject: Simplify broadcast calls --- src/main/java/org/traccar/MainEventHandler.java | 1 - src/main/java/org/traccar/api/BaseObjectResource.java | 6 ------ src/main/java/org/traccar/api/resource/DeviceResource.java | 1 - .../java/org/traccar/api/resource/PermissionsResource.java | 10 ---------- src/main/java/org/traccar/notificators/NotificatorWeb.java | 1 - src/main/java/org/traccar/session/ConnectionManager.java | 11 +++++++++-- src/main/java/org/traccar/session/cache/CacheManager.java | 8 +++++++- 7 files changed, 16 insertions(+), 22 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index e2cad15c6..981888577 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -93,7 +93,6 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { cacheManager.updatePosition(position); connectionManager.updatePosition(true, position); - broadcastService.updatePosition(true, position); } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 403021c6c..489360619 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -16,7 +16,6 @@ */ package org.traccar.api; -import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Group; @@ -42,9 +41,6 @@ public abstract class BaseObjectResource extends BaseResour @Inject private CacheManager cacheManager; - @Inject - private BroadcastService broadcastService; - protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -72,7 +68,6 @@ public abstract class BaseObjectResource extends BaseResour LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); - broadcastService.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); @@ -99,7 +94,6 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); cacheManager.updateOrInvalidate(entity); - broadcastService.invalidateObject(entity.getClass(), entity.getId()); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index e205f2d28..8791a82f9 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -138,7 +138,6 @@ public class DeviceResource extends BaseObjectResource { cacheManager.addDevice(position.getDeviceId()); cacheManager.updatePosition(position); connectionManager.updatePosition(true, position); - broadcastService.updatePosition(true, position); } finally { cacheManager.removeDevice(position.getDeviceId()); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 5ca865c31..44fc897ac 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -17,7 +17,6 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.Permission; import org.traccar.model.UserRestrictions; @@ -46,9 +45,6 @@ public class PermissionsResource extends BaseResource { @Inject private CacheManager cacheManager; - @Inject - private BroadcastService broadcastService; - private void checkPermission(Permission permission) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -78,9 +74,6 @@ public class PermissionsResource extends BaseResource { cacheManager.invalidatePermission( permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - broadcastService.invalidatePermission( - permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); @@ -105,9 +98,6 @@ public class PermissionsResource extends BaseResource { cacheManager.invalidatePermission( permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - broadcastService.invalidatePermission( - permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 061018ba9..f495042a5 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -57,7 +57,6 @@ public final class NotificatorWeb implements Notificator { copy.set("message", message.getBody()); connectionManager.updateEvent(true, user.getId(), copy); - broadcastService.updateEvent(true, user.getId(), copy); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 0e0ea1eb8..c2f602c11 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -285,7 +285,6 @@ public class ConnectionManager implements BroadcastInterface { } updateDevice(true, device); - broadcastService.updateDevice(true, device); } public DeviceState getDeviceState(long deviceId) { @@ -324,7 +323,9 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void updateDevice(boolean local, Device device) { - if (!local && Device.STATUS_ONLINE.equals(device.getStatus())) { + if (local) { + broadcastService.updateDevice(true, device); + } else if (Device.STATUS_ONLINE.equals(device.getStatus())) { timeouts.remove(device.getId()); removeDeviceSession(device.getId()); } @@ -339,6 +340,9 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void updatePosition(boolean local, Position position) { + if (local) { + broadcastService.updatePosition(true, position); + } for (long userId : deviceUsers.getOrDefault(position.getDeviceId(), Collections.emptySet())) { if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { @@ -350,6 +354,9 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void updateEvent(boolean local, long userId, Event event) { + if (local) { + broadcastService.updateEvent(true, userId, event); + } if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { listener.onUpdateEvent(event); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index d2ada7d43..bc5fc357f 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -58,6 +58,7 @@ public class CacheManager implements BroadcastInterface { private final Config config; private final Storage storage; + private final BroadcastService broadcastService; private final ReadWriteLock lock = new ReentrantReadWriteLock(); @@ -73,9 +74,10 @@ public class CacheManager implements BroadcastInterface { public CacheManager(Config config, Storage storage, BroadcastService broadcastService) throws StorageException { this.config = config; this.storage = storage; - broadcastService.registerListener(this); + this.broadcastService = broadcastService; invalidateServer(); invalidateUsers(); + broadcastService.registerListener(this); } public Config getConfig() { @@ -198,6 +200,8 @@ public class CacheManager implements BroadcastInterface { } public void updateOrInvalidate(T object) throws StorageException { + broadcastService.invalidateObject(object.getClass(), object.getId()); + boolean invalidate = false; var before = getObject(object.getClass(), object.getId()); if (before == null) { @@ -231,6 +235,8 @@ public class CacheManager implements BroadcastInterface { public void invalidatePermission( Class clazz1, long id1, Class clazz2, long id2) { + broadcastService.invalidatePermission(clazz1, id1, clazz2, id2); + try { invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); } catch (StorageException e) { -- cgit v1.2.3 From 2812c02d18ccf3ad9fadab921516cd5ff8755668 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Jun 2022 16:51:51 -0700 Subject: Missing SMTP config error --- src/main/java/org/traccar/database/MailManager.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index ac0db2d97..0c868e1fc 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -16,8 +16,6 @@ */ package org.traccar.database; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; @@ -38,8 +36,6 @@ import java.util.Properties; public final class MailManager { - private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); - private final Config config; private final StatisticsManager statisticsManager; @@ -115,8 +111,7 @@ public final class MailManager { properties = getProperties(new PropertiesProvider(config)); } if (!properties.containsKey("mail.smtp.host")) { - LOGGER.warn("No SMTP configuration found"); - return; + throw new RuntimeException("No SMTP configuration found"); } Session session = Session.getInstance(properties); -- cgit v1.2.3 From 08d634d984c1388c3919d7c6645506b202307dac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Jun 2022 18:43:15 -0700 Subject: Temporary disable group lookup --- src/main/java/org/traccar/helper/model/AttributeUtil.java | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 58b922d95..b438f97dc 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -19,7 +19,6 @@ import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; import org.traccar.config.Keys; import org.traccar.model.Device; -import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; public final class AttributeUtil { @@ -31,13 +30,6 @@ public final class AttributeUtil { public static T lookup(CacheManager cacheManager, ConfigKey key, long deviceId) { Device device = cacheManager.getObject(Device.class, deviceId); Object result = device.getAttributes().get(key.getKey()); - long groupId = device.getGroupId(); - while (result == null && groupId > 0) { - Group group = cacheManager.getObject(Group.class, groupId); - if (group != null) { - result = group.getAttributes().get(key.getKey()); - } - } if (result == null && key.hasType(KeyType.SERVER)) { result = cacheManager.getServer().getAttributes().get(key.getKey()); } -- cgit v1.2.3 From 3c48c66cf55705274ff482cf3deefee11196ddfe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 07:19:24 -0700 Subject: Fix user registration --- src/main/java/org/traccar/api/resource/UserResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 20fce9e32..1bb399437 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -72,8 +72,8 @@ public class UserResource extends BaseObjectResource { @PermitAll @POST public Response add(User entity) throws StorageException { - User currentUser = permissionsService.getUser(getUserId()); - if (permissionsService.notAdmin(getUserId())) { + User currentUser = getUserId() > 0 ? permissionsService.getUser(getUserId()) : null; + if (currentUser == null || !currentUser.getAdministrator()) { permissionsService.checkUserUpdate(getUserId(), new User(), entity); if (currentUser != null && currentUser.getUserLimit() != 0) { int userLimit = currentUser.getUserLimit(); -- cgit v1.2.3 From 9e07a009a3da41cd3cdd21809e9588e1ed133d6f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 07:39:33 -0700 Subject: Fix device name in reports --- .../org/traccar/reports/StopsReportProvider.java | 10 ++++---- .../org/traccar/reports/SummaryReportProvider.java | 20 ++++++++-------- .../org/traccar/reports/TripsReportProvider.java | 15 ++++++------ .../org/traccar/reports/common/ReportUtils.java | 27 ++++++++-------------- 4 files changed, 32 insertions(+), 40 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 6e4cd74d6..ba61ef6a1 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -55,10 +55,10 @@ public class StopsReportProvider { this.storage = storage; } - private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { + private Collection detectStops(Device device, Date from, Date to) throws StorageException { boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); - return reportUtils.detectTripsAndStops( - PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, StopReportItem.class); + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); + return reportUtils.detectTripsAndStops(device, positions, ignoreOdometer, StopReportItem.class); } public Collection getObjects( @@ -68,7 +68,7 @@ public class StopsReportProvider { ArrayList result = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - result.addAll(detectStops(device.getId(), from, to)); + result.addAll(detectStops(device, from, to)); } return result; } @@ -81,7 +81,7 @@ public class StopsReportProvider { ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - Collection stops = detectStops(device.getId(), from, to); + Collection stops = detectStops(device, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 26d79c899..02033b9e5 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -58,11 +58,10 @@ public class SummaryReportProvider { this.storage = storage; } - private SummaryReportItem calculateSummaryResult( - long deviceId, Collection positions) throws StorageException { + private SummaryReportItem calculateSummaryResult(Device device, Collection positions) { SummaryReportItem result = new SummaryReportItem(); - result.setDeviceId(deviceId); - result.setDeviceName(reportUtils.getDevice(deviceId).getName()); + result.setDeviceId(device.getId()); + result.setDeviceName(device.getName()); if (positions != null && !positions.isEmpty()) { Position firstPosition = null; Position previousPosition = null; @@ -119,9 +118,9 @@ public class SummaryReportProvider { } private Collection calculateSummaryResults( - long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { + long userId, Device device, Date from, Date to, boolean daily) throws StorageException { - var positions = PositionUtil.getPositions(storage, deviceId, from, to); + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); var results = new ArrayList(); if (daily && !positions.isEmpty()) { int startIndex = 0; @@ -129,14 +128,14 @@ public class SummaryReportProvider { for (int i = 0; i < positions.size(); i++) { int currentDay = getDay(userId, positions.get(i).getFixTime()); if (currentDay != startDay) { - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, i))); + results.add(calculateSummaryResult(device, positions.subList(startIndex, i))); startIndex = i; startDay = currentDay; } } - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, positions.size()))); + results.add(calculateSummaryResult(device, positions.subList(startIndex, positions.size()))); } else { - results.add(calculateSummaryResult(deviceId, positions)); + results.add(calculateSummaryResult(device, positions)); } return results; @@ -149,8 +148,7 @@ public class SummaryReportProvider { ArrayList result = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - Collection deviceResults = - calculateSummaryResults(userId, device.getId(), from, to, daily); + Collection deviceResults = calculateSummaryResults(userId, device, from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { result.add(summaryReport); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 7d10879b7..2d9bcdfbf 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -55,19 +55,20 @@ public class TripsReportProvider { this.storage = storage; } - private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { + private Collection detectTrips(Device device, Date from, Date to) throws StorageException { boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); - return reportUtils.detectTripsAndStops( - PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, TripReportItem.class); + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); + return reportUtils.detectTripsAndStops(device, positions, ignoreOdometer, TripReportItem.class); } - public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { + public Collection getObjects( + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - result.addAll(detectTrips(device.getId(), from, to)); + result.addAll(detectTrips(device, from, to)); } return result; } @@ -80,7 +81,7 @@ public class TripsReportProvider { ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - Collection trips = detectTrips(device.getId(), from, to); + Collection trips = detectTrips(device, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index f5f2cd3df..cd6b6ffd5 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -99,12 +99,6 @@ public class ReportUtils { new Condition.Permission(User.class, userId, clazz)))); } - public Device getDevice(long deviceId) throws StorageException { - return storage.getObject(Device.class, new Request( - new Columns.Include("id"), - new Condition.Equals("id", "id", deviceId))); - } - public void checkPeriodLimit(Date from, Date to) { long limit = config.getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { @@ -211,7 +205,7 @@ public class ReportUtils { } private TripReportItem calculateTrip( - ArrayList positions, int startIndex, int endIndex, + Device device, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) throws StorageException { Position startTrip = positions.get(startIndex); @@ -230,7 +224,7 @@ public class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(getDevice(deviceId).getName()); + trip.setDeviceName(device.getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -277,8 +271,7 @@ public class ReportUtils { } private StopReportItem calculateStop( - ArrayList positions, int startIndex, int endIndex, - boolean ignoreOdometer) throws StorageException { + Device device, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -287,7 +280,7 @@ public class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(getDevice(deviceId).getName()); + stop.setDeviceName(device.getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); @@ -326,13 +319,13 @@ public class ReportUtils { @SuppressWarnings("unchecked") private T calculateTripOrStop( - ArrayList positions, int startIndex, int endIndex, + Device device, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(device, positions, startIndex, endIndex, ignoreOdometer); } else { - return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateStop(device, positions, startIndex, endIndex, ignoreOdometer); } } @@ -357,7 +350,7 @@ public class ReportUtils { } public Collection detectTripsAndStops( - Collection positionCollection, boolean ignoreOdometer, + Device device, Collection positionCollection, boolean ignoreOdometer, Class reportClass) throws StorageException { Collection result = new ArrayList<>(); @@ -392,14 +385,14 @@ public class ReportUtils { if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { result.add(calculateTripOrStop( - positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + device, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { int endIndex = startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1; result.add(calculateTripOrStop( - positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); + device, positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); } } -- cgit v1.2.3 From a487c1efa5dff2a7644ee7f2874967f4bb867b6a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 08:13:03 -0700 Subject: Fix new device updates --- src/main/java/org/traccar/api/BaseObjectResource.java | 5 +++++ src/main/java/org/traccar/session/ConnectionManager.java | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 489360619..d10843917 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -21,6 +21,7 @@ import org.traccar.model.BaseModel; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -41,6 +42,9 @@ public abstract class BaseObjectResource extends BaseResour @Inject private CacheManager cacheManager; + @Inject + private ConnectionManager connectionManager; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -68,6 +72,7 @@ public abstract class BaseObjectResource extends BaseResour LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); + connectionManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index c2f602c11..27d6184c2 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -364,6 +364,18 @@ public class ConnectionManager implements BroadcastInterface { } } + @Override + public synchronized void invalidatePermission( + Class clazz1, long id1, + Class clazz2, long id2) { + if (clazz1.equals(User.class) && clazz2.equals(Device.class)) { + if (listeners.containsKey(id1)) { + userDevices.get(id1).add(id2); + deviceUsers.put(id2, Set.of(id1)); + } + } + } + public interface UpdateListener { void onKeepalive(); void onUpdateDevice(Device device); @@ -379,7 +391,7 @@ public class ConnectionManager implements BroadcastInterface { var devices = storage.getObjects(Device.class, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))); - userDevices.put(userId, devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet())); + userDevices.put(userId, devices.stream().map(BaseModel::getId).collect(Collectors.toSet())); devices.forEach(device -> deviceUsers.computeIfAbsent(device.getId(), id -> new HashSet<>()).add(userId)); } set.add(listener); -- cgit v1.2.3 From 9345f8e086105ba30e9e9cf87b3fc5b0740d68e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 10:47:42 -0700 Subject: Fix device creation issue --- src/main/java/org/traccar/api/security/PermissionsService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index e5bc52f22..a3e7a182f 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -102,8 +102,9 @@ public class PermissionsService { if (getServer().getReadonly() || getUser(userId).getReadonly()) { denied = true; } else if (clazz.equals(Device.class)) { - denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly(); - if (addition) { + denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly() + || addition && getUser(userId).getDeviceLimit() == 0; + if (addition && getUser(userId).getDeviceLimit() > 0) { int deviceCount = storage.getObjects(Device.class, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))).size(); -- cgit v1.2.3 From 7899f1ffbb0e00243d2b4cf72ffe9bc59bb920bc Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Wed, 29 Jun 2022 09:02:15 +0200 Subject: time advance moved to inner block added a check for 0 mac address on wifi networks. --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 35fdc3ca5..a71c5606d 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -142,8 +142,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Network network = new Network(); int cellCount = Integer.parseInt(values[index++]); - index += 1; // timing advance if (cellCount > 0) { + index += 1; // timing advance int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; @@ -164,8 +164,11 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < wifiCount; i++) { index += 1; // wifi name - network.addWifiAccessPoint(WifiAccessPoint.from( - values[index++], Integer.parseInt(values[index++]))); + String macAddress = values[index++]; + String rssi = values[index++]; + if (!macAddress.isEmpty() && !macAddress.equals("0") && !rssi.isEmpty()) { + network.addWifiAccessPoint(WifiAccessPoint.from(macAddress, Integer.parseInt(rssi))); + } } } -- cgit v1.2.3 From d9f127b979ff52731552edecd1d0762c21eb4403 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 07:16:25 -0700 Subject: Better MAC address validation --- src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java | 3 ++- src/test/java/org/traccar/ProtocolTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java index a45c315b3..635806b2d 100644 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -116,8 +116,9 @@ public class B2316ProtocolDecoder extends BaseProtocolDecoder { String[] points = item.getString("wi").split(";"); for (String point : points) { String[] values = point.split(","); + String mac = values[0].replaceAll("(..)", "$1:"); network.addWifiAccessPoint(WifiAccessPoint.from( - values[0].replaceAll("(..)", "$1:"), Integer.parseInt(values[1]))); + mac.substring(0, mac.length() - 1), Integer.parseInt(values[1]))); } } diff --git a/src/test/java/org/traccar/ProtocolTest.java b/src/test/java/org/traccar/ProtocolTest.java index 3e27bbe28..5e37f44b9 100644 --- a/src/test/java/org/traccar/ProtocolTest.java +++ b/src/test/java/org/traccar/ProtocolTest.java @@ -323,7 +323,7 @@ public class ProtocolTest extends BaseTest { if (position.getNetwork().getWifiAccessPoints() != null) { for (WifiAccessPoint wifiAccessPoint : position.getNetwork().getWifiAccessPoints()) { - assertTrue("validation failed for mac address with zero value", !wifiAccessPoint.getMacAddress().equals("0")); + assertTrue(wifiAccessPoint.getMacAddress().matches("((\\p{XDigit}{2}):){5}(\\p{XDigit}{2})")); } } } -- cgit v1.2.3 From aed0411f4ae5cfc007d27e0521a39a242fab7840 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 17:03:23 -0700 Subject: Unify signed magnitude int decoding --- src/main/java/org/traccar/helper/BitUtil.java | 4 ++-- src/main/java/org/traccar/helper/BufferUtil.java | 6 ++++++ .../java/org/traccar/protocol/NiotProtocolDecoder.java | 11 +++-------- .../java/org/traccar/protocol/SigfoxProtocolDecoder.java | 15 +++------------ .../java/org/traccar/protocol/SuntechProtocolDecoder.java | 13 +++---------- .../org/traccar/protocol/ThinkPowerProtocolDecoder.java | 1 + src/test/java/org/traccar/helper/BufferUtilTest.java | 6 ++++++ 7 files changed, 24 insertions(+), 32 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/BitUtil.java b/src/main/java/org/traccar/helper/BitUtil.java index b6108edff..829ddebc9 100644 --- a/src/main/java/org/traccar/helper/BitUtil.java +++ b/src/main/java/org/traccar/helper/BitUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 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. @@ -21,7 +21,7 @@ public final class BitUtil { } public static boolean check(long number, int index) { - return (number & (1 << index)) != 0; + return (number & (1L << index)) != 0; } public static int between(int number, int from, int to) { diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index 1e1a687fa..0dbe0a4ad 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -27,6 +27,12 @@ public final class BufferUtil { private BufferUtil() { } + public static int readSignedMagnitudeInt(ByteBuf buffer) { + long value = buffer.readUnsignedInt(); + int result = (int) BitUtil.to(value, 31); + return BitUtil.check(value, 31) ? -result : result; + } + public static int indexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value, int count) { int startIndex = fromIndex; for (int i = 0; i < count; i++) { diff --git a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java index 16d992938..35614ccca 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BufferUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -57,12 +58,6 @@ public class NiotProtocolDecoder extends BaseProtocolDecoder { } } - private double readCoordinate(ByteBuf buf) { - long value = buf.readUnsignedInt(); - double result = BitUtil.to(value, 31) / 1800000.0; - return BitUtil.check(value, 31) ? -result : result; - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -96,8 +91,8 @@ public class NiotProtocolDecoder extends BaseProtocolDecoder { .setSecond(BcdUtil.readInteger(buf, 2)); position.setTime(dateBuilder.getDate()); - position.setLatitude(readCoordinate(buf)); - position.setLongitude(readCoordinate(buf)); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) / 1800000.0); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) / 1800000.0); BcdUtil.readInteger(buf, 4); // reserved position.setCourse(BcdUtil.readInteger(buf, 4)); diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index bbb8bc1cc..4ed2bb51d 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -22,6 +22,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.helper.BufferUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -159,18 +160,8 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { if (event == 0x0f || event == 0x1f) { position.setValid(event >> 4 > 0); - - long value; - value = buf.readUnsignedInt(); - position.setLatitude(BitUtil.to(value, 31) * 0.000001); - if (BitUtil.check(value, 31)) { - position.setLatitude(-position.getLatitude()); - } - value = buf.readUnsignedInt(); - position.setLongitude(BitUtil.to(value, 31) * 0.000001); - if (BitUtil.check(value, 31)) { - position.setLongitude(-position.getLongitude()); - } + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.000001); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.000001); position.set(Position.KEY_BATTERY, (int) buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 67a82a688..938d290c0 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -21,6 +21,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.config.Keys; +import org.traccar.helper.BufferUtil; import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; @@ -673,19 +674,11 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 11)) { - long value = buf.readUnsignedInt(); - if (BitUtil.check(value, 31)) { - value = -BitUtil.to(value, 31); - } - position.setLatitude(value / 1000000.0); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) / 1000000.0); } if (BitUtil.check(mask, 12)) { - long value = buf.readUnsignedInt(); - if (BitUtil.check(value, 31)) { - value = -BitUtil.to(value, 31); - } - position.setLongitude(value / 1000000.0); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) / 1000000.0); } if (BitUtil.check(mask, 13)) { diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index 085ce4c91..26d60daba 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BitUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; diff --git a/src/test/java/org/traccar/helper/BufferUtilTest.java b/src/test/java/org/traccar/helper/BufferUtilTest.java index b539b5b28..0196cef9d 100644 --- a/src/test/java/org/traccar/helper/BufferUtilTest.java +++ b/src/test/java/org/traccar/helper/BufferUtilTest.java @@ -10,6 +10,12 @@ import static org.junit.Assert.assertEquals; public class BufferUtilTest { + @Test + public void testReadSignedMagnitudeInt() { + ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex("80000001")); + assertEquals(-1, BufferUtil.readSignedMagnitudeInt(buf)); + } + @Test public void test1() { ByteBuf buf = Unpooled.copiedBuffer("abcdef", StandardCharsets.US_ASCII); -- cgit v1.2.3 From ef523bb4db2c48d7d07a326157d5758199ed293f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 17:04:30 -0700 Subject: Fix ThinkPower negative coords --- src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index 26d60daba..e7ab23e5b 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.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. @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.helper.BitUtil; +import org.traccar.helper.BufferUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -65,8 +65,8 @@ public class ThinkPowerProtocolDecoder extends BaseProtocolDecoder { switch (type) { case 0x01: position.setValid(true); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort() * 0.01); break; -- cgit v1.2.3 From e374041be79c95465cb4aea4d482ee90f5e531f5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 17:33:08 -0700 Subject: Decode TLW2-12BL network info --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 3 ++- src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index b7a89f2e9..6e09e6e3b 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -58,6 +58,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_DRIVER_BEHAVIOR_1 = 0x05; // 0x2626 public static final int MSG_DRIVER_BEHAVIOR_2 = 0x06; // 0x2626 public static final int MSG_BLE = 0x10; + public static final int MSG_NETWORK_2 = 0x11; public static final int MSG_GPS_2 = 0x13; public static final int MSG_ALARM_2 = 0x14; public static final int MSG_COMMAND = 0x81; @@ -167,7 +168,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return decodePosition(channel, deviceSession, buf, type, index, imei); - } else if (type == MSG_NETWORK && header == 0x2727) { + } else if (type == MSG_NETWORK && header == 0x2727 || type == MSG_NETWORK_2) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java index b5917e3cc..10d0aad59 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class T800xProtocolDecoderTest extends ProtocolTest { var decoder = inject(new T800xProtocolDecoder(null)); + verifyAttributes(decoder, binary( + "2525110055000208677300508924902206262035310c540045004c00430045004c0004454447450847534d20313930300f323134303734323036373835323839143839333430373131373930303936383037363846")); + verifyAttributes(decoder, binary( "27271000247bd00860112047066487210407034238000005d7d17365e625ff640a730148")); -- cgit v1.2.3 From 1089b4bd2c9721f88a898c69385ae3fcac4b6cbe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 19:02:15 -0700 Subject: Fix P61 battery decoding --- src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 7 ++++--- .../java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index ebd58ed5c..4cb4b420d 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -360,15 +360,16 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("d*,") .number("(x{1,2}),") // report type .number("d{1,2},") // count + .number("d*,").optional() // reserved .expression(PATTERN_LOCATION.pattern()) .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer + .number("(?:(d{1,7}.d)|0)?,").optional() // odometer .number("(d{1,3})?,") // battery .or() .number("(d{1,7}.d)?,") // odometer .groupEnd() .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) + .number("(dd)(dd)(dd)") // time (hhmmss) .text(",") .number("(xxxx)") // count number .text("$").optional() diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 6857feddc..1140aa110 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "+RESP:GTNMR,423033,355197370058831,,0,0,0,1,0,0.0,298,182.7,-79.257983,43.875152,20220627132020,,,,,15,0,74,20220627144928,03CF$"), + Position.KEY_BATTERY_LEVEL, 74); + verifyPosition(decoder, buffer( "+RESP:GTFRI,5E0100,861971050039361,,,,10,1,1,10.4,140,196.9,-80.709946,35.016525,20220302220944,0310,0260,1CE9,52A1,00,0.0,,,,,420000,,,,20220302220948,1B0B$")); -- cgit v1.2.3 From 418e7ce116dd6c19b594f14ba220d3bdb905241c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 19:23:19 -0700 Subject: Decode GV350MG driver warnings --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 42 ++++++++++++++++++++++ .../protocol/Gl200TextProtocolDecoderTest.java | 4 +++ 2 files changed, 46 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 4cb4b420d..517499f02 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -352,6 +352,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_DAR = new PatternBuilder() + .text("+RESP:GTDAR,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(d),") // warning type + .number("(d{1,2}),,,") // fatigue degree + .expression(PATTERN_LOCATION.pattern()) + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF):GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -1126,6 +1142,29 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeDar(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_DAR, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int warningType = parser.nextInt(); + int fatigueDegree = parser.nextInt(); + if (warningType == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + position.set("fatigueDegree", fatigueDegree); + } else { + position.set("warningType", warningType); + } + + decodeLocation(position, parser); + + decodeDeviceTime(position, parser); + + return position; + } + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { Parser parser = new Parser(PATTERN, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1317,6 +1356,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "PFA": result = decodePna(channel, remoteAddress, sentence); break; + case "DAR": + result = decodeDar(channel, remoteAddress, sentence); + break; default: result = decodeOther(channel, remoteAddress, sentence, type); break; diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 1140aa110..ef82a11a2 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "+RESP:GTDAR,F10406,865284049582228,,4,0,,,1,18.5,0,129.4,114.015430,22.537279,20210922004634,0460,0000,27BD,0DFC,,,,20210922004635,082B$"), + "warningType", 4); + verifyAttribute(decoder, buffer( "+RESP:GTNMR,423033,355197370058831,,0,0,0,1,0,0.0,298,182.7,-79.257983,43.875152,20220627132020,,,,,15,0,74,20220627144928,03CF$"), Position.KEY_BATTERY_LEVEL, 74); -- cgit v1.2.3 From 8ea427480417580aab51ed8f291f53a4051c79ee Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 07:52:02 -0700 Subject: Extract device lookup --- .../org/traccar/database/DeviceLookupService.java | 57 ++++++++++++++++++++++ .../org/traccar/session/ConnectionManager.java | 19 +++----- 2 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/traccar/database/DeviceLookupService.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java new file mode 100644 index 000000000..f0a4e7bf0 --- /dev/null +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -0,0 +1,57 @@ +/* + * 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.database; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class DeviceLookupService { + + private static final Logger LOGGER = LoggerFactory.getLogger(DeviceLookupService.class); + + private final Storage storage; + + @Inject + public DeviceLookupService(Storage storage) { + this.storage = storage; + } + + public Device lookup(String[] uniqueIds) { + Device device = null; + try { + for (String uniqueId : uniqueIds) { + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); + if (device != null) { + break; + } + } + } catch (Exception e) { + LOGGER.warn("Find device error", e); + } + return device; + } + +} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 27d6184c2..abc13988d 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -26,6 +26,7 @@ import org.traccar.broadcast.BroadcastInterface; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.DeviceLookupService; import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; @@ -76,6 +77,7 @@ public class ConnectionManager implements BroadcastInterface { private final NotificationManager notificationManager; private final Timer timer; private final BroadcastService broadcastService; + private final DeviceLookupService deviceLookupService; private final Map> listeners = new HashMap<>(); private final Map> userDevices = new HashMap<>(); @@ -86,7 +88,8 @@ public class ConnectionManager implements BroadcastInterface { @Inject public ConnectionManager( Injector injector, Config config, CacheManager cacheManager, Storage storage, - NotificationManager notificationManager, Timer timer, BroadcastService broadcastService) { + NotificationManager notificationManager, Timer timer, BroadcastService broadcastService, + DeviceLookupService deviceLookupService) { this.injector = injector; this.config = config; this.cacheManager = cacheManager; @@ -94,6 +97,7 @@ public class ConnectionManager implements BroadcastInterface { this.notificationManager = notificationManager; this.timer = timer; this.broadcastService = broadcastService; + this.deviceLookupService = deviceLookupService; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); broadcastService.registerListener(this); @@ -121,18 +125,7 @@ public class ConnectionManager implements BroadcastInterface { return endpointSessions.values().stream().findAny().orElse(null); } - Device device = null; - try { - for (String uniqueId : uniqueIds) { - device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); - if (device != null) { - break; - } - } - } catch (Exception e) { - LOGGER.warn("Find device error", e); - } + Device device = deviceLookupService.lookup(uniqueIds); if (device == null && config.getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { device = addUnknownDevice(uniqueIds[0]); -- cgit v1.2.3 From 29ad12512ba5e109e78a3c8384ae10747e1eabec Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 09:12:01 -0700 Subject: Device lookup throttling --- .../org/traccar/database/DeviceLookupService.java | 83 ++++++++++++++++++++-- 1 file changed, 77 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index f0a4e7bf0..9cf0899ee 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -15,40 +15,111 @@ */ package org.traccar.database; +import io.netty.util.Timeout; +import io.netty.util.Timer; +import io.netty.util.TimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.Device; import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; @Singleton public class DeviceLookupService { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceLookupService.class); + private static final long INFO_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(60); + private static final long THROTTLE_MIN_MS = TimeUnit.MINUTES.toMillis(1); + private static final long THROTTLE_MAX_MS = TimeUnit.MINUTES.toMillis(30); + private final Storage storage; + private final Timer timer; + + private static class IdentifierInfo { + private long lastQuery; + private long delay; + private Timeout timeout; + } + + private final class IdentifierTask implements TimerTask { + private final String uniqueId; + + private IdentifierTask(String uniqueId) { + this.uniqueId = uniqueId; + } + + @Override + public void run(Timeout timeout) { + LOGGER.debug("Device lookup expired {}", uniqueId); + synchronized (DeviceLookupService.this) { + identifierMap.remove(uniqueId); + } + } + } + + private final Map identifierMap = new ConcurrentHashMap<>(); @Inject - public DeviceLookupService(Storage storage) { + public DeviceLookupService(Storage storage, Timer timer) { this.storage = storage; + this.timer = timer; + } + + private synchronized boolean isThrottled(String uniqueId) { + IdentifierInfo info = identifierMap.get(uniqueId); + return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + } + + private synchronized void lookupSucceeded(String uniqueId) { + IdentifierInfo info = identifierMap.remove(uniqueId); + if (info != null) { + info.timeout.cancel(); + } + } + + private synchronized void lookupFailed(String uniqueId) { + IdentifierInfo info = identifierMap.get(uniqueId); + if (info != null) { + info.timeout.cancel(); + info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); + } else { + info = new IdentifierInfo(); + identifierMap.put(uniqueId, info); + info.delay = THROTTLE_MIN_MS; + } + info.lastQuery = System.currentTimeMillis(); + info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); + LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } public Device lookup(String[] uniqueIds) { Device device = null; try { for (String uniqueId : uniqueIds) { - device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); - if (device != null) { - break; + if (!isThrottled(uniqueId)) { + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); + if (device != null) { + lookupSucceeded(uniqueId); + break; + } else { + lookupFailed(uniqueId); + } + } else { + LOGGER.debug("Device lookup throttled {}", uniqueId); } } - } catch (Exception e) { + } catch (StorageException e) { LOGGER.warn("Find device error", e); } return device; -- cgit v1.2.3 From 45c076da2d5be1cad89a9a7e1c0dc2d3755bd7b5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 09:15:19 -0700 Subject: Fix online device removal --- .../org/traccar/session/cache/CacheManager.java | 56 +++++++++++----------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index bc5fc357f..9d1db7d14 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -268,38 +268,40 @@ public class CacheManager implements BroadcastInterface { Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.Equals("id", "id", deviceId))); - addObject(deviceId, device); + if (device != null) { + addObject(deviceId, device); + + for (Class clazz : CLASSES) { + var objects = storage.getObjects(clazz, new Request( + new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); + links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); + objects.forEach(object -> addObject(deviceId, object)); + } - for (Class clazz : CLASSES) { - var objects = storage.getObjects(clazz, new Request( - new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); - links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); - objects.forEach(object -> addObject(deviceId, object)); - } + var users = storage.getObjects(User.class, new Request( + new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); + links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); + for (var user : users) { + addObject(deviceId, user); + var notifications = storage.getObjects(Notification.class, new Request( + new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); + notifications.stream() + .filter(Notification::getAlways) + .forEach(object -> { + links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); + addObject(deviceId, object); + }); + } - var users = storage.getObjects(User.class, new Request( - new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); - links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); - for (var user : users) { - addObject(deviceId, user); - var notifications = storage.getObjects(Notification.class, new Request( - new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); - notifications.stream() - .filter(Notification::getAlways) - .forEach(object -> { - links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); - addObject(deviceId, object); - }); - } + deviceLinks.put(deviceId, links); - deviceLinks.put(deviceId, links); + if (device.getPositionId() > 0) { + devicePositions.put(deviceId, storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + } - if (device.getPositionId() > 0) { - devicePositions.put(deviceId, storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + invalidateDeviceGeofences(device); } - - invalidateDeviceGeofences(device); } private void unsafeRemoveDevice(long deviceId) { -- cgit v1.2.3 From d7c1345f6f070e3931af0ad3fac785130cc9f4dc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 17:16:03 -0700 Subject: Fix group attribute lookup (fix #4880) --- src/main/java/org/traccar/helper/model/AttributeUtil.java | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index b438f97dc..43558e8f7 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -19,6 +19,7 @@ import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; import org.traccar.config.Keys; import org.traccar.model.Device; +import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; public final class AttributeUtil { @@ -30,6 +31,16 @@ public final class AttributeUtil { public static T lookup(CacheManager cacheManager, ConfigKey key, long deviceId) { Device device = cacheManager.getObject(Device.class, deviceId); Object result = device.getAttributes().get(key.getKey()); + long groupId = device.getGroupId(); + while (result == null && groupId > 0) { + Group group = cacheManager.getObject(Group.class, groupId); + if (group != null) { + result = group.getAttributes().get(key.getKey()); + groupId = group.getGroupId(); + } else { + groupId = 0; + } + } if (result == null && key.hasType(KeyType.SERVER)) { result = cacheManager.getServer().getAttributes().get(key.getKey()); } -- cgit v1.2.3 From 771f334d686b252b3b6975beb758c3833e85f0f2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 17:55:43 -0700 Subject: Check for attribute --- src/main/java/org/traccar/handler/CopyAttributesHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 405a52ecd..50d36471a 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -44,7 +44,7 @@ public class CopyAttributesHandler extends BaseDataHandler { String attributesString = AttributeUtil.lookup( cacheManager, Keys.PROCESSING_COPY_ATTRIBUTES, position.getDeviceId()); Position last = cacheManager.getPosition(position.getDeviceId()); - if (last != null) { + if (last != null && attributesString != null) { for (String attribute : attributesString.split("[ ,]")) { if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) { -- cgit v1.2.3 From 8c4499a8fa5e30a498d9357b16b56cd65fbe1e39 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 1 Jul 2022 10:01:45 -0700 Subject: Fix duplicated users --- src/main/java/org/traccar/session/cache/CacheManager.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 9d1db7d14..cd71f5f9f 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -249,6 +249,7 @@ public class CacheManager implements BroadcastInterface { } private void invalidateUsers() throws StorageException { + notificationUsers.clear(); Map users = new HashMap<>(); storage.getObjects(User.class, new Request(new Columns.All())) .forEach(user -> users.put(user.getId(), user)); -- cgit v1.2.3 From 95ba3446d936213683d604eb545710124b9bf689 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 2 Jul 2022 09:06:49 -0700 Subject: Add broadcast logging --- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index ac0fcbd86..81b6cd5ec 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -159,6 +159,7 @@ public class MulticastBroadcastService implements BroadcastService { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + LOGGER.info("Broadcast received: {}", data); handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } socket.leaveGroup(address); -- cgit v1.2.3 From 5f88528350f55802d63bfcb0f4902a4a3399634c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Jul 2022 13:03:24 -0700 Subject: Fix server update --- src/main/java/org/traccar/api/resource/ServerResource.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 2ef99c578..071b7ae8e 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -22,9 +22,10 @@ import org.traccar.helper.Log; import org.traccar.helper.LogAction; import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.storage.Storage; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.annotation.Nullable; @@ -48,7 +49,7 @@ import java.util.TimeZone; public class ServerResource extends BaseResource { @Inject - private Storage storage; + private CacheManager cacheManager; @Inject private MailManager mailManager; @@ -72,6 +73,10 @@ public class ServerResource extends BaseResource { @PUT public Response update(Server entity) throws StorageException { permissionsService.checkAdmin(getUserId()); + storage.updateObject(entity, new Request( + new Columns.Exclude("id"), + new Condition.Equals("id", "id"))); + cacheManager.updateOrInvalidate(entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); } -- cgit v1.2.3 From c49bda5396847731f4eea8f6e3f0e0dd6811ae6f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Jul 2022 15:52:39 -0700 Subject: Support KML export (fix #1858, fix #2329) --- .../org/traccar/api/resource/PositionResource.java | 21 ++++++ .../org/traccar/reports/KmlExportProvider.java | 80 ++++++++++++++++++++++ tools/test-generator.py | 7 +- 3 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/traccar/reports/KmlExportProvider.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index cac64feb1..28f8eb600 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -20,17 +20,22 @@ import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; +import org.traccar.reports.KmlExportProvider; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -41,6 +46,9 @@ import java.util.List; @Consumes(MediaType.APPLICATION_JSON) public class PositionResource extends BaseResource { + @Inject + private KmlExportProvider kmlExportProvider; + @GET public Collection getJson( @QueryParam("deviceId") long deviceId, @QueryParam("id") List positionIds, @@ -69,4 +77,17 @@ public class PositionResource extends BaseResource { } } + @Path("kml") + @GET + @Produces("application/vnd.google-earth.kml+xml") + public Response getKml( + @QueryParam("deviceId") long deviceId, + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + kmlExportProvider.generateKml(stream, deviceId, from, to); + return Response.ok(stream.toByteArray()) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.kml").build(); + } + } diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java new file mode 100644 index 000000000..977897833 --- /dev/null +++ b/src/main/java/org/traccar/reports/KmlExportProvider.java @@ -0,0 +1,80 @@ +/* + * 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.reports; + +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.stream.Collectors; + +public class KmlExportProvider { + + private final Storage storage; + + @Inject + public KmlExportProvider(Storage storage) { + this.storage = storage; + } + + public void generateKml( + OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { + + var device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + + var dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + + try (PrintWriter writer = new PrintWriter(outputStream)) { + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(device.getName()); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(dateFormat.format(from)); + writer.print(" - "); + writer.print(dateFormat.format(to)); + writer.print(""); + writer.print(""); + writer.print("1"); + writer.print("1"); + writer.print("absolute"); + writer.print(""); + writer.print(positions.stream() + .map((p -> String.format("%f,%f,%f", p.getLongitude(), p.getLatitude(), p.getAltitude()))) + .collect(Collectors.joining(" "))); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + } + } + +} diff --git a/tools/test-generator.py b/tools/test-generator.py index b8a06ac32..eb50d2600 100755 --- a/tools/test-generator.py +++ b/tools/test-generator.py @@ -35,8 +35,8 @@ for i in range(0, len(waypoints)): lon = lon1 + (lon2 - lon1) * j / count points.append((lat, lon)) -def send(conn, lat, lon, course, speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId): - params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('bearing', course), ('speed', speed), ('batt', battery)) +def send(conn, lat, lon, altitude, course, speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId): + params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('altitude', altitude), ('bearing', course), ('speed', speed), ('batt', battery)) if alarm: params = params + (('alarm', 'sos'),) if ignition: @@ -70,6 +70,7 @@ conn = httplib.HTTPConnection(server) while True: (lat1, lon1) = points[index % len(points)] (lat2, lon2) = points[(index + 1) % len(points)] + altitude = 50 speed = device_speed if (index % len(points)) != 0 else 0 alarm = (index % 10) == 0 battery = random.randint(0, 100) @@ -78,6 +79,6 @@ while True: rpm = random.randint(500, 4000) fuel = random.randint(0, 80) driverUniqueId = driver_id if (index % len(points)) == 0 else False - send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId) + send(conn, lat1, lon1, altitude, course(lat1, lon1, lat2, lon2), speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId) time.sleep(period) index += 1 -- cgit v1.2.3 From d25e8a163786c78098c57bb78cf44746c1fe2364 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Jul 2022 16:02:49 -0700 Subject: Geocoder enabled server flag --- src/main/java/org/traccar/api/resource/ServerResource.java | 1 + src/main/java/org/traccar/model/Server.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 071b7ae8e..3e6792f5b 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -63,6 +63,7 @@ public class ServerResource extends BaseResource { public Server get() throws StorageException { Server server = storage.getObject(Server.class, new Request(new Columns.All())); server.setEmailEnabled(mailManager.getEmailEnabled()); + server.setGeocoderEnabled(geocoder != null); User user = permissionsService.getUser(getUserId()); if (user != null && user.getAdministrator()) { server.setStorageSpace(Log.getStorageSpace()); diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 648be2991..e39da1b16 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -214,6 +214,18 @@ public class Server extends ExtendedModel implements UserRestrictions { return emailEnabled; } + private boolean geocoderEnabled; + + @QueryIgnore + public void setGeocoderEnabled(boolean geocoderEnabled) { + this.geocoderEnabled = geocoderEnabled; + } + + @QueryIgnore + public boolean getGeocoderEnabled() { + return geocoderEnabled; + } + private long[] storageSpace; @QueryIgnore -- cgit v1.2.3 From 0112af2cf93743b2bcec0e16cd0d95bcc9713f3f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Jul 2022 09:26:43 -0700 Subject: Add device image upload --- .../org/traccar/api/resource/DeviceResource.java | 36 +++++++++++++++++++++- .../java/org/traccar/database/MediaManager.java | 5 +++ 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 8791a82f9..1d9bc20ec 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseObjectResource; import org.traccar.broadcast.BroadcastService; +import org.traccar.database.MediaManager; import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; @@ -32,12 +33,18 @@ import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.Collection; import java.util.LinkedList; @@ -57,6 +64,9 @@ public class DeviceResource extends BaseObjectResource { @Inject private BroadcastService broadcastService; + @Inject + private MediaManager mediaManager; + public DeviceResource() { super(Device.class); } @@ -110,7 +120,7 @@ public class DeviceResource extends BaseObjectResource { @Path("{id}/accumulators") @PUT - public Response updateAccumulators(DeviceAccumulators entity) throws StorageException, IOException { + public Response updateAccumulators(DeviceAccumulators entity) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkManager(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); @@ -149,4 +159,28 @@ public class DeviceResource extends BaseObjectResource { return Response.noContent().build(); } + @Path("{id}/image") + @POST + @Consumes("image/*") + public Response uploadImage( + @PathParam("id") long deviceId, File file, + @HeaderParam(HttpHeaders.CONTENT_TYPE) String type) throws StorageException, IOException { + + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("id", "id", deviceId), + new Condition.Permission(User.class, getUserId(), Device.class)))); + if (device != null) { + String name = "device"; + String extension = type.substring("image/".length()); + try (var input = new FileInputStream(file); + var output = mediaManager.createFileStream(device.getUniqueId(), name, extension)) { + input.transferTo(output); + } + return Response.ok(name + "." + extension).build(); + } + return Response.status(Response.Status.NOT_FOUND).build(); + } + } diff --git a/src/main/java/org/traccar/database/MediaManager.java b/src/main/java/org/traccar/database/MediaManager.java index 5f3fdcdf7..2b3e3e1ee 100644 --- a/src/main/java/org/traccar/database/MediaManager.java +++ b/src/main/java/org/traccar/database/MediaManager.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Files; @@ -53,6 +54,10 @@ public class MediaManager { return filePath.toFile(); } + public OutputStream createFileStream(String uniqueId, String name, String extension) throws IOException { + return new FileOutputStream(createFile(uniqueId, name + "." + extension)); + } + public String writeFile(String uniqueId, ByteBuf buf, String extension) { if (path != null) { int size = buf.readableBytes(); -- cgit v1.2.3 From 8a5dbe0a1bd68c21d4c1e06a55e1190246774a1f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Jul 2022 14:30:11 -0700 Subject: Implement CSV export (fix #2961) --- .../org/traccar/api/resource/PositionResource.java | 36 ++++++++-- src/main/java/org/traccar/model/Position.java | 1 - .../org/traccar/reports/CsvExportProvider.java | 76 ++++++++++++++++++++++ .../org/traccar/reports/KmlExportProvider.java | 2 +- 4 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/traccar/reports/CsvExportProvider.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 28f8eb600..b4c8d18b9 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -20,6 +20,7 @@ import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; +import org.traccar.reports.CsvExportProvider; import org.traccar.reports.KmlExportProvider; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -32,10 +33,11 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.io.ByteArrayOutputStream; +import javax.ws.rs.core.StreamingOutput; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -49,6 +51,9 @@ public class PositionResource extends BaseResource { @Inject private KmlExportProvider kmlExportProvider; + @Inject + private CsvExportProvider csvExportProvider; + @GET public Collection getJson( @QueryParam("deviceId") long deviceId, @QueryParam("id") List positionIds, @@ -84,10 +89,33 @@ public class PositionResource extends BaseResource { @QueryParam("deviceId") long deviceId, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkPermission(Device.class, getUserId(), deviceId); - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - kmlExportProvider.generateKml(stream, deviceId, from, to); - return Response.ok(stream.toByteArray()) + StreamingOutput stream = output -> { + try { + kmlExportProvider.generate(output, deviceId, from, to); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.kml").build(); } + @Path("csv") + @GET + @Produces("text/csv") + public Response getCsv( + @QueryParam("deviceId") long deviceId, + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + StreamingOutput stream = output -> { + try { + csvExportProvider.generate(output, deviceId, from, to); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.csv").build(); + } + } diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 348370e2c..d6c985458 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -150,7 +150,6 @@ public class Position extends Message { public Position(String protocol) { this.protocol = protocol; - this.serverTime = new Date(); } private String protocol; diff --git a/src/main/java/org/traccar/reports/CsvExportProvider.java b/src/main/java/org/traccar/reports/CsvExportProvider.java new file mode 100644 index 000000000..df55c470e --- /dev/null +++ b/src/main/java/org/traccar/reports/CsvExportProvider.java @@ -0,0 +1,76 @@ +/* + * 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.reports; + +import org.traccar.helper.DateUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; + +import javax.inject.Inject; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class CsvExportProvider { + + private final Storage storage; + + @Inject + public CsvExportProvider(Storage storage) { + this.storage = storage; + } + + public void generate( + OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { + + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + + var attributes = positions.stream() + .flatMap((position -> position.getAttributes().keySet().stream())) + .collect(Collectors.toUnmodifiableSet()); + + var properties = new LinkedHashMap>(); + properties.put("id", Position::getId); + properties.put("deviceId", Position::getDeviceId); + properties.put("protocol", Position::getProtocol); + properties.put("serverTime", position -> DateUtil.formatDate(position.getServerTime())); + properties.put("deviceTime", position -> DateUtil.formatDate(position.getDeviceTime())); + properties.put("fixTime", position -> DateUtil.formatDate(position.getFixTime())); + properties.put("valid", Position::getValid); + properties.put("latitude", Position::getLatitude); + properties.put("longitude", Position::getLongitude); + properties.put("altitude", Position::getAltitude); + properties.put("speed", Position::getSpeed); + properties.put("course", Position::getCourse); + properties.put("address", Position::getAddress); + properties.put("accuracy", Position::getAccuracy); + attributes.forEach(key -> properties.put(key, position -> position.getAttributes().get(key))); + + try (PrintWriter writer = new PrintWriter(outputStream)) { + writer.println(String.join(",", properties.keySet())); + positions.forEach(position -> writer.println(properties.values().stream() + .map(f -> Objects.toString(f.apply(position), "")) + .collect(Collectors.joining(",")))); + } + } + +} diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java index 977897833..e8b5c4278 100644 --- a/src/main/java/org/traccar/reports/KmlExportProvider.java +++ b/src/main/java/org/traccar/reports/KmlExportProvider.java @@ -39,7 +39,7 @@ public class KmlExportProvider { this.storage = storage; } - public void generateKml( + public void generate( OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { var device = storage.getObject(Device.class, new Request( -- cgit v1.2.3 From 0b463a40998baf05cc84cb4400ab58e6e11c909d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Jul 2022 15:25:03 -0700 Subject: Additional report endpoints --- .../org/traccar/api/resource/ReportResource.java | 221 ++++++++++++++------- 1 file changed, 154 insertions(+), 67 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 3955f1d20..6176013c1 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -16,26 +16,6 @@ */ package org.traccar.api.resource; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import javax.activation.DataHandler; -import javax.inject.Inject; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.util.ByteArrayDataSource; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.BaseResource; @@ -46,15 +26,38 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.reports.EventsReportProvider; +import org.traccar.reports.RouteReportProvider; +import org.traccar.reports.StopsReportProvider; import org.traccar.reports.SummaryReportProvider; import org.traccar.reports.TripsReportProvider; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.SummaryReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.reports.RouteReportProvider; -import org.traccar.reports.StopsReportProvider; import org.traccar.storage.StorageException; +import javax.activation.DataHandler; +import javax.inject.Inject; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javax.mail.util.ByteArrayDataSource; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; +import java.util.Date; +import java.util.List; + @Path("reports") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -62,8 +65,7 @@ public class ReportResource extends BaseResource { private static final Logger LOGGER = LoggerFactory.getLogger(ReportResource.class); - private static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - private static final String CONTENT_DISPOSITION_VALUE_XLSX = "attachment; filename=report.xlsx"; + private static final String EXCEL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; @Inject private EventsReportProvider eventsReportProvider; @@ -84,19 +86,18 @@ public class ReportResource extends BaseResource { private MailManager mailManager; private interface ReportExecutor { - void execute(ByteArrayOutputStream stream) throws StorageException, IOException; + void execute(OutputStream stream) throws StorageException, IOException; } private Response executeReport( - long userId, boolean mail, ReportExecutor executor) throws StorageException, IOException { - final ByteArrayOutputStream stream = new ByteArrayOutputStream(); + long userId, boolean mail, ReportExecutor executor) { if (mail) { new Thread(() -> { try { + var stream = new ByteArrayOutputStream(); executor.execute(stream); MimeBodyPart attachment = new MimeBodyPart(); - attachment.setFileName("report.xlsx"); attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( stream.toByteArray(), "application/octet-stream"))); @@ -109,17 +110,25 @@ public class ReportResource extends BaseResource { }).start(); return Response.noContent().build(); } else { - executor.execute(stream); - return Response.ok(stream.toByteArray()) - .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build(); + StreamingOutput stream = output -> { + try { + executor.execute(output); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=report.xlsx").build(); } } @Path("route") @GET public Collection getRoute( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return routeReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -127,11 +136,13 @@ public class ReportResource extends BaseResource { @Path("route") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getRouteExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); @@ -139,12 +150,26 @@ public class ReportResource extends BaseResource { }); } + @Path("route/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getRouteExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") final List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getRouteExcel(deviceIds, groupIds, from, to, type.equals("mail")); + } + @Path("events") @GET public Collection getEvents( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("type") final List types, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("type") List types, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return eventsReportProvider.getObjects(getUserId(), deviceIds, groupIds, types, from, to); @@ -152,12 +177,14 @@ public class ReportResource extends BaseResource { @Path("events") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getEventsExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("type") final List types, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("type") List types, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); @@ -165,12 +192,27 @@ public class ReportResource extends BaseResource { }); } + @Path("events/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getEventsExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("type") List types, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getEventsExcel(deviceIds, groupIds, types, from, to, type.equals("mail")); + } + @Path("summary") @GET public Collection getSummary( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) - throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("daily") boolean daily) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return summaryReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); @@ -178,12 +220,14 @@ public class ReportResource extends BaseResource { @Path("summary") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getSummaryExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, - @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("daily") boolean daily, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); @@ -191,12 +235,26 @@ public class ReportResource extends BaseResource { }); } + @Path("summary/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getSummaryExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("daily") boolean daily, + @PathParam("type") String type) throws StorageException { + return getSummaryExcel(deviceIds, groupIds, from, to, daily, type.equals("mail")); + } + @Path("trips") @GET - @Produces(MediaType.APPLICATION_JSON) public Collection getTrips( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return tripsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -204,11 +262,13 @@ public class ReportResource extends BaseResource { @Path("trips") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getTripsExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); @@ -216,12 +276,25 @@ public class ReportResource extends BaseResource { }); } + @Path("trips/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getTripsExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getTripsExcel(deviceIds, groupIds, from, to, type.equals("mail")); + } + @Path("stops") @GET - @Produces(MediaType.APPLICATION_JSON) public Collection getStops( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return stopsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -229,11 +302,13 @@ public class ReportResource extends BaseResource { @Path("stops") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getStopsExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); @@ -241,4 +316,16 @@ public class ReportResource extends BaseResource { }); } + @Path("stops/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getStopsExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getStopsExcel(deviceIds, groupIds, from, to, type.equals("mail")); + } + } -- cgit v1.2.3 From 715499d5eabf73bdd1684bcf87006d904c92414b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 5 Jul 2022 17:12:08 -0700 Subject: Trim Suntech serial data --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 938d290c0..52fdaa05c 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -400,7 +400,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } } } else { - position.set("serial", attribute); + position.set("serial", attribute.trim()); } remaining -= attribute.length() + 1; } diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 71f71ce99..30959c8b9 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -95,6 +95,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, binary( "53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b30")); + verifyAttribute(decoder, buffer( + "ST300UEX;511248287;45;311;20220701;18:42:08;14c943;-22.975257;-043.373065;000.000;000.00;0;0;0;12.14;100010;19;RFID:008FB2BEBA39\r\n;3E;000135;4.1;1;00000000000000;0"), + "serial", "RFID:008FB2BEBA39"); + verifyAttribute(decoder, buffer( "ST300UEX;100850000;01;010;20081017;07:41:56;2F100;+37.478519;+126.886819;000.012;000.00;9;1;0;15.30;001100;25;Welcome to Suntech World!;12;0;4.5;1"), "serial", "Welcome to Suntech World!"); -- cgit v1.2.3 From 09eebb35449c4ffb43b6a72bb4c3f723ec1c84be Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Jul 2022 16:19:56 -0700 Subject: Remove motion fallback (fix #3257) --- src/main/java/org/traccar/reports/common/ReportUtils.java | 7 +------ src/test/java/org/traccar/reports/ReportUtilsTest.java | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index cd6b6ffd5..ce5e3d8d4 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -341,12 +341,7 @@ public class ReportUtils { return false; } } - if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) - && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { - return positions.get(index).getBoolean(Position.KEY_MOTION); - } else { - return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); - } + return positions.get(index).getBoolean(Position.KEY_MOTION); } public Collection detectTripsAndStops( diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index b73ae7cc0..aecb1c4a4 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -57,6 +57,7 @@ public class ReportUtilsTest extends BaseTest { position.setTime(date(time)); position.setValid(true); position.setSpeed(speed); + position.set(Position.KEY_MOTION, speed > 0); position.set(Position.KEY_TOTAL_DISTANCE, totalDistance); return position; -- cgit v1.2.3 From 30d920c2e49c4022af8590c7d200907cde16d1c9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 7 Jul 2022 17:28:49 -0700 Subject: Decode Concox CRX1 serial --- .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 15 ++++++++++----- .../org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index c53fbfe5a..63210b2fa 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1004,11 +1004,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (subType == 0x1b) { - buf.readUnsignedByte(); // header - buf.readUnsignedByte(); // type - position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); - buf.readUnsignedByte(); // checksum - buf.readUnsignedByte(); // footer + if (Character.isLetter(buf.getUnsignedByte(buf.readerIndex()))) { + String data = buf.readCharSequence(buf.readableBytes() - 6, StandardCharsets.US_ASCII).toString(); + position.set("serial", data.trim()); + } else { + buf.readUnsignedByte(); // header + buf.readUnsignedByte(); // type + position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); + buf.readUnsignedByte(); // checksum + buf.readUnsignedByte(); // footer + } return position; } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 5b355e4f5..8c54fe3e4 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "79790019941b524649443a3030384642324245424133390d0a000c14930d0a"), + "serial", "RFID:008FB2BEBA39"); + verifyAttribute(decoder, binary( "7878241216040e102c22cf00915ffb04c6016300195a02d402283b00753f400571040001dda4880d0a"), Position.KEY_IGNITION, false); -- cgit v1.2.3 From 54d7f988b449fabbbd10fb123d63502d2427b43b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Jul 2022 09:21:39 -0700 Subject: Fix Galileo array decoding --- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 3 +-- src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index bf14d47e0..0a57087fe 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -213,7 +213,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); break; case 0xea: - position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); break; default: diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index d76fc5895..f9bdd6b42 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "011801018202130338363833343530333230343234323604640010a406207caa9f5b300c830a7901ca0ec802330000000034b802350540003e41703f422b1043234504004600e09000000000a000a100a200a300a400a500a600a700a800a900aa00ab00ac00ad00ae00af00b00000b10000b20000b30000b40000b50000b60000b70000b80000b90000c000000000c100000000c200000000c300000000c400c500c600c700c800c900ca00cb00cc00cd00ce00cf00d000d100d200d4d3140000d60000d70000d80000d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000f400000000f500000000f600000000f700000000f800000000f9000000008960")); + verifyPositions(decoder, binary( + "01bf83043200101ee4209832bc62300549589302511aaa013300002e00342e02350440003b41b15d42d50e4326450e0046040050000051000052fc5c5300006100008b009000000000d400000000e201000000e376000000e4efce0100e53b590200e600000000e773000000e800000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101de4201232bc62300549589302511aaa013300002e00342e02350440012b41b55d42d40e4326450e0046040050000051000052145d5300006100008b009000000000d400000000e201000000e376000000e4efce0100e53b590200e600000000e773000000e800000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101ce4208e2ebc62300549589302511aaa013300002e00342e02350440013b41a95d42cd0e4325450f0046040050000051000052235d5300006100008b009000000000d400000000e201000000e376000000e4efce0100e53b590200e600000000e773000000e802000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101be4208b2ebc62300549589302511aaa013300002e00342e02350440013b41a45d42cd0e432545090046040050000051000052115d5300006100008b009000000000d400000000e201000000e375000000e48ac90100e53a590200e673000000e773000000e806000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101ae420642ebc62300549589302511aaa013300002e00342e02350440013b419f5d42cd0e4324450b00460600500000519313521c5d5300006100008b009000000000d400000000e201000000e300000000e406000000e5c5580200e673000000e700000000e801000000e9a002d007ea140000d6021b00f8430220ac7600000000000000000432001019e420632ebc62300549589302511aaa013300002e00342e02350440013b41725d42cd0e4324450b0046060050000051ab1352035d5300006100008b009000000000d400000000e201000000e300000000e406000000e5c5580200e673000000e700000000e8d6021b00e9a002d007ea140000d6021b00f8430220ac7600000000000000000432001018e4205c2ebc62300549589302511aaa013300002e00342e02350440013b41955d42cd0e4324450a00460400500000510000520b5d5300006100008b009000000000d400000000e201000000e30d000000e4a4350000e5c5580200e600000000e700000000e8d6021b00e9a002d007ea140000d6021b00f8430220ac76000000000000000099f3")); + verifyPositions(decoder, binary( "017583018202120338363833343530333230363635373304520010384520c850975b300cc03a910107cbf9023365000607341300350640012a41236a4215104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d4993b0500d64100d70000d8be02d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000018202120338363833343530333230363635373304520010394520c950975b300cab3a91010ecbf902336000be06341300350640012a41266a4216104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d49b3b0500d64100d70000d8bc02d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f3000000000182021203383638333435303332303636353733045200103a4520ca50975b300c953a910113cbf9023358008f06341300350640012a41206a4215104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d49e3b0500d64100d70000d8ba02d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f3000000000182021203383638333435303332303636353733045200103b45204251975b300c6d3a91011dcbf9023300008a06341300350640013a41726a4216104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d4a33b0500d64800d70000d80003d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f3000000000182021203383638333435303332303636353733045200103c4520bb51975b300c6d3a91011dcbf9023300008a06341300350640013a41816a4216104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d4a33b0500d64800d70000d80003d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000e007")); -- cgit v1.2.3 From eec839e7f47843629b4c730c765bb7605f50532e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 10:26:44 -0700 Subject: Support SR411 mini variant --- .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 15 +++++++++++++++ .../org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 18 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 63210b2fa..b65e4a4b8 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -112,6 +112,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private enum Variant { VXT01, WANWAY_S20, + SR411_MINI, GT06E_CARD, BENWAY, S5, @@ -646,6 +647,18 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_LBS_MULTIPLE_3 && variant == Variant.SR411_MINI) { + + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); + + decodeLbs(position, buf, type, false); + + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + + return position; + } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { @@ -1323,6 +1336,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x31) { variant = Variant.WANWAY_S20; + } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x2e) { + variant = Variant.SR411_MINI; } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length >= 0x71) { variant = Variant.GT06E_CARD; } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x21) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 8c54fe3e4..f3f47a104 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyPosition(decoder, binary( + "78782e2416061a103600c80275298404a0a24000184602d4023a49006f060104ed01940000086508004139765000be7d640d0a")); + verifyAttribute(decoder, binary( "79790019941b524649443a3030384642324245424133390d0a000c14930d0a"), "serial", "RFID:008FB2BEBA39"); -- cgit v1.2.3 From e3c98044a2deba5ea6ece533cfe860e03e985fb9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 16:03:42 -0700 Subject: Fix decoder injection --- src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java | 10 +++++++++- src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java index 68a70c944..361eeeef2 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.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. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; +import com.google.inject.Injector; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import javax.inject.Inject; import java.net.SocketAddress; public class ArnaviProtocolDecoder extends BaseProtocolDecoder { @@ -33,6 +35,12 @@ public class ArnaviProtocolDecoder extends BaseProtocolDecoder { binaryProtocolDecoder = new ArnaviBinaryProtocolDecoder(protocol); } + @Inject + public void setInjector(Injector injector) { + injector.injectMembers(textProtocolDecoder); + injector.injectMembers(binaryProtocolDecoder); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java index ca1df7a13..a9736c9e7 100644 --- a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 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. @@ -15,12 +15,14 @@ */ package org.traccar.protocol; +import com.google.inject.Injector; import org.traccar.BaseProtocolDecoder; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.Protocol; +import javax.inject.Inject; import java.net.SocketAddress; public class Gl200ProtocolDecoder extends BaseProtocolDecoder { @@ -34,6 +36,12 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { binaryProtocolDecoder = new Gl200BinaryProtocolDecoder(protocol); } + @Inject + public void setInjector(Injector injector) { + injector.injectMembers(textProtocolDecoder); + injector.injectMembers(binaryProtocolDecoder); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { -- cgit v1.2.3 From 6bf82f7e29e78c9ef4eab22530749991f420b2aa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 16:56:36 -0700 Subject: Filter null unique ids --- src/main/java/org/traccar/protocol/WialonProtocolDecoder.java | 2 +- src/main/java/org/traccar/session/ConnectionManager.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 8dd7aab24..3d57525b7 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -39,7 +39,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN_ANY = new PatternBuilder() - .expression("([^#]*)?") // imei + .expression("([^#]+)?") // imei .text("#") // start byte .expression("([^#]+)") // type .text("#") // separator diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index abc13988d..ad02c591b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -47,11 +47,13 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -114,6 +116,8 @@ public class ConnectionManager implements BroadcastInterface { Endpoint endpoint = new Endpoint(channel, remoteAddress); Map endpointSessions = sessionsByEndpoint.getOrDefault( endpoint, new ConcurrentHashMap<>()); + + uniqueIds = Arrays.stream(uniqueIds).filter(Objects::nonNull).toArray(String[]::new); if (uniqueIds.length > 0) { for (String uniqueId : uniqueIds) { DeviceSession deviceSession = endpointSessions.get(uniqueId); -- cgit v1.2.3 From 65cb239b78d3e75db565309b0196378e29a439d4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 10 Jul 2022 10:25:25 -0700 Subject: Specify multicast interface --- .../broadcast/MulticastBroadcastService.java | 22 ++++++++++++++++------ src/main/java/org/traccar/config/Keys.java | 7 +++++++ 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 81b6cd5ec..877008eda 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -30,7 +30,9 @@ import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.MulticastSocket; +import java.net.NetworkInterface; import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.Map; @@ -44,8 +46,9 @@ public class MulticastBroadcastService implements BroadcastService { private final ObjectMapper objectMapper; - private final InetAddress address; + private final NetworkInterface networkInterface; private final int port; + private final InetSocketAddress group; private DatagramSocket publisherSocket; @@ -56,8 +59,15 @@ public class MulticastBroadcastService implements BroadcastService { public MulticastBroadcastService(Config config, ObjectMapper objectMapper) throws IOException { this.objectMapper = objectMapper; - address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); port = config.getInteger(Keys.BROADCAST_PORT); + String interfaceName = config.getString(Keys.BROADCAST_INTERFACE); + if (interfaceName.indexOf('.') >= 0 || interfaceName.indexOf(':') >= 0) { + networkInterface = NetworkInterface.getByInetAddress(InetAddress.getByName(interfaceName)); + } else { + networkInterface = NetworkInterface.getByName(interfaceName); + } + InetAddress address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); + group = new InetSocketAddress(address, port); } @Override @@ -106,7 +116,7 @@ public class MulticastBroadcastService implements BroadcastService { private void sendMessage(BroadcastMessage message) { try { byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); - DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group); publisherSocket.send(packet); } catch (IOException e) { LOGGER.warn("Broadcast failed", e); @@ -150,11 +160,10 @@ public class MulticastBroadcastService implements BroadcastService { } private final Runnable receiver = new Runnable() { - @SuppressWarnings("deprecation") @Override public void run() { try (MulticastSocket socket = new MulticastSocket(port)) { - socket.joinGroup(address); + socket.joinGroup(group, networkInterface); while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); @@ -162,10 +171,11 @@ public class MulticastBroadcastService implements BroadcastService { LOGGER.info("Broadcast received: {}", data); handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } - socket.leaveGroup(address); + socket.leaveGroup(group, networkInterface); } catch (IOException e) { throw new RuntimeException(e); } } }; + } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 8e11b4013..6f19ee863 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1444,6 +1444,13 @@ public final class Keys { List.of(KeyType.CONFIG), "time,position,speed,course,accuracy,result"); + /** + * Multicast interface. It can be either an IP address or an interface name. + */ + public static final ConfigKey BROADCAST_INTERFACE = new StringConfigKey( + "broadcast.interface", + List.of(KeyType.CONFIG)); + /** * Multicast address for broadcasting synchronization events. */ -- cgit v1.2.3 From e5fed94589cff4614b248cb3408397febc0b1be7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 07:20:34 -0700 Subject: Use same socket for sending --- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 877008eda..134bba797 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -150,12 +150,10 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void start() throws IOException { service.submit(receiver); - publisherSocket = new DatagramSocket(); } @Override public void stop() { - publisherSocket.close(); service.shutdown(); } @@ -163,6 +161,7 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void run() { try (MulticastSocket socket = new MulticastSocket(port)) { + publisherSocket = socket; socket.joinGroup(group, networkInterface); while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); @@ -172,6 +171,7 @@ public class MulticastBroadcastService implements BroadcastService { handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } socket.leaveGroup(group, networkInterface); + publisherSocket = null; } catch (IOException e) { throw new RuntimeException(e); } -- cgit v1.2.3 From 767a449904b3d154ded4c5facefc73d7e33650f1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 17:58:35 -0700 Subject: Interface for sending multicast --- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 134bba797..c4ba0e059 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -161,17 +161,17 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void run() { try (MulticastSocket socket = new MulticastSocket(port)) { - publisherSocket = socket; + socket.setNetworkInterface(networkInterface); socket.joinGroup(group, networkInterface); + publisherSocket = socket; while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); - LOGGER.info("Broadcast received: {}", data); handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } - socket.leaveGroup(group, networkInterface); publisherSocket = null; + socket.leaveGroup(group, networkInterface); } catch (IOException e) { throw new RuntimeException(e); } -- cgit v1.2.3 From 42140ceae97b3da66a54b0b5480242adf0b4e23e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 20:34:34 -0700 Subject: Simplify timeout units --- src/main/java/org/traccar/session/ConnectionManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index ad02c591b..d4bb9b4b1 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -100,7 +100,7 @@ public class ConnectionManager implements BroadcastInterface { this.timer = timer; this.broadcastService = broadcastService; this.deviceLookupService = deviceLookupService; - deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; + deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT); updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); broadcastService.registerListener(this); } @@ -270,7 +270,7 @@ public class ConnectionManager implements BroadcastInterface { if (!timeout1.isCancelled()) { deviceUnknown(deviceId); } - }, deviceTimeout, TimeUnit.MILLISECONDS)); + }, deviceTimeout, TimeUnit.SECONDS)); } try { -- cgit v1.2.3 From 7ccffa266e87badbbcfde73db86216fd4c667f35 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 20:35:07 -0700 Subject: Fix offline notifications (fix #4889) --- .../java/org/traccar/database/NotificationManager.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 1314a3d0a..ecb44b1d4 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -99,15 +99,13 @@ public class NotificationManager { notifications.forEach(notification -> { cacheManager.getNotificationUsers(notification.getId()).forEach(user -> { - new Thread(() -> { - for (String notificator : notification.getNotificatorsTypes()) { - try { - notificatorManager.getNotificator(notificator).send(user, event, position); - } catch (MessageException | InterruptedException exception) { - LOGGER.warn("Notification failed", exception); - } + for (String notificator : notification.getNotificatorsTypes()) { + try { + notificatorManager.getNotificator(notificator).send(user, event, position); + } catch (MessageException | InterruptedException exception) { + LOGGER.warn("Notification failed", exception); } - }).start(); + } }); }); } -- cgit v1.2.3 From 3f46f759c24746ddd2b8cd05cfc6cb99d5f7fd48 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 11:06:22 -0700 Subject: Filter notifications by device access (fix #4888) --- src/main/java/org/traccar/database/NotificationManager.java | 2 +- src/main/java/org/traccar/session/cache/CacheManager.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index ecb44b1d4..5be627f2a 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -98,7 +98,7 @@ public class NotificationManager { } notifications.forEach(notification -> { - cacheManager.getNotificationUsers(notification.getId()).forEach(user -> { + cacheManager.getNotificationUsers(notification.getId(), event.getDeviceId()).forEach(user -> { for (String notificator : notification.getNotificatorsTypes()) { try { notificatorManager.getNotificator(notificator).send(user, event, position); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index cd71f5f9f..c1697faf9 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -123,10 +123,14 @@ public class CacheManager implements BroadcastInterface { } } - public List getNotificationUsers(long notificationId) { + public List getNotificationUsers(long notificationId, long deviceId) { try { lock.readLock().lock(); - return notificationUsers.get(notificationId); + var users = deviceLinks.get(deviceId).get(User.class).stream() + .collect(Collectors.toUnmodifiableSet()); + return notificationUsers.get(notificationId).stream() + .filter(user -> users.contains(user.getId())) + .collect(Collectors.toUnmodifiableList()); } finally { lock.readLock().unlock(); } -- cgit v1.2.3 From 98e2db95f73cb85a2623e2902741bcb4e73683e5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 16:50:26 -0700 Subject: Remove extended query annotation --- src/main/java/org/traccar/model/Device.java | 3 +-- src/main/java/org/traccar/model/User.java | 9 ++++---- .../java/org/traccar/storage/QueryExtended.java | 27 ---------------------- .../java/org/traccar/storage/query/Columns.java | 2 -- 4 files changed, 5 insertions(+), 36 deletions(-) delete mode 100644 src/main/java/org/traccar/storage/QueryExtended.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 219f078ed..35eb757f2 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -18,7 +18,6 @@ package org.traccar.model; import java.util.Date; import java.util.List; -import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -67,7 +66,7 @@ public class Device extends GroupedModel { return this.lastUpdate; } - @QueryExtended + @QueryIgnore public void setLastUpdate(Date lastUpdate) { this.lastUpdate = lastUpdate; } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 12fd03d45..9dd84ad14 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -17,7 +17,6 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import org.traccar.helper.Hashing; import org.traccar.storage.StorageName; @@ -271,12 +270,12 @@ public class User extends ExtendedModel implements UserRestrictions { private String hashedPassword; @JsonIgnore - @QueryExtended + @QueryIgnore public String getHashedPassword() { return hashedPassword; } - @QueryExtended + @QueryIgnore public void setHashedPassword(String hashedPassword) { this.hashedPassword = hashedPassword; } @@ -284,12 +283,12 @@ public class User extends ExtendedModel implements UserRestrictions { private String salt; @JsonIgnore - @QueryExtended + @QueryIgnore public String getSalt() { return salt; } - @QueryExtended + @QueryIgnore public void setSalt(String salt) { this.salt = salt; } diff --git a/src/main/java/org/traccar/storage/QueryExtended.java b/src/main/java/org/traccar/storage/QueryExtended.java deleted file mode 100644 index 3796f1f40..000000000 --- a/src/main/java/org/traccar/storage/QueryExtended.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.storage; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface QueryExtended { -} diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 97ca13be9..545995b3c 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -15,7 +15,6 @@ */ package org.traccar.storage.query; -import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import java.lang.reflect.Method; @@ -36,7 +35,6 @@ public abstract class Columns { int parameterCount = type.equals("set") ? 1 : 0; if (method.getName().startsWith(type) && method.getParameterTypes().length == parameterCount && !method.isAnnotationPresent(QueryIgnore.class) - && !method.isAnnotationPresent(QueryExtended.class) && !method.getName().equals("getClass")) { columns.add(method.getName().substring(3).toLowerCase()); } -- cgit v1.2.3 From 493ff1068ea3e4d96f2475234b265b47cce8691f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 17:31:36 -0700 Subject: Persist device status (fix #4890, fix #4891) --- schema/changelog-5.2.xml | 21 +++++++++++++++++++++ schema/changelog-master.xml | 1 + .../handler/events/GeofenceEventHandler.java | 21 +++++++++++++++++++-- src/main/java/org/traccar/model/Device.java | 4 +--- .../java/org/traccar/session/ConnectionManager.java | 13 +++++++------ .../org/traccar/session/cache/CacheManager.java | 14 -------------- 6 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 schema/changelog-5.2.xml (limited to 'src/main/java/org') diff --git a/schema/changelog-5.2.xml b/schema/changelog-5.2.xml new file mode 100644 index 000000000..1ac9eedc5 --- /dev/null +++ b/schema/changelog-5.2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 471b0fe5d..83a1ac865 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -32,5 +32,6 @@ + diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index ca3fc3f89..70bdb84cb 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -26,6 +26,11 @@ import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.ArrayList; @@ -39,12 +44,15 @@ public class GeofenceEventHandler extends BaseEventHandler { private final Config config; private final CacheManager cacheManager; private final ConnectionManager connectionManager; + private final Storage storage; @Inject - public GeofenceEventHandler(Config config, CacheManager cacheManager, ConnectionManager connectionManager) { + public GeofenceEventHandler( + Config config, CacheManager cacheManager, ConnectionManager connectionManager, Storage storage) { this.config = config; this.cacheManager = cacheManager; this.connectionManager = connectionManager; + this.storage = storage; } @Override @@ -66,8 +74,17 @@ public class GeofenceEventHandler extends BaseEventHandler { newGeofences.removeAll(oldGeofences); oldGeofences.removeAll(currentGeofences); - device.setGeofenceIds(currentGeofences); + if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) { + device.setGeofenceIds(currentGeofences.isEmpty() ? null : currentGeofences); + + try { + storage.updateObject(device, new Request( + new Columns.Include("geofenceIds"), new Condition.Equals("id", "id"))); + } catch (StorageException e) { + throw new RuntimeException("Update device geofences error", e); + } + connectionManager.updateDevice(true, device); } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 35eb757f2..6593c59b0 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -50,14 +50,13 @@ public class Device extends GroupedModel { private String status; - @QueryIgnore public String getStatus() { return status != null ? status : STATUS_OFFLINE; } @QueryIgnore public void setStatus(String status) { - this.status = status; + this.status = status.trim(); } private Date lastUpdate; @@ -85,7 +84,6 @@ public class Device extends GroupedModel { private List geofenceIds; - @QueryIgnore public List getGeofenceIds() { return geofenceIds; } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index d4bb9b4b1..62fdd833b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -52,6 +52,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -256,15 +257,15 @@ public class ConnectionManager implements BroadcastInterface { notificationManager.updateEvents(events); } + if (time != null) { + device.setLastUpdate(time); + } + Timeout timeout = timeouts.remove(deviceId); if (timeout != null) { timeout.cancel(); } - if (time != null) { - device.setLastUpdate(time); - } - if (status.equals(Device.STATUS_ONLINE)) { timeouts.put(deviceId, timer.newTimeout(timeout1 -> { if (!timeout1.isCancelled()) { @@ -275,7 +276,7 @@ public class ConnectionManager implements BroadcastInterface { try { storage.updateObject(device, new Request( - new Columns.Include("lastUpdate"), + new Columns.Include("status", "lastUpdate"), new Condition.Equals("id", "id"))); } catch (StorageException e) { LOGGER.warn("Update device status error", e); @@ -368,7 +369,7 @@ public class ConnectionManager implements BroadcastInterface { if (clazz1.equals(User.class) && clazz2.equals(Device.class)) { if (listeners.containsKey(id1)) { userDevices.get(id1).add(id2); - deviceUsers.put(id2, Set.of(id1)); + deviceUsers.put(id2, new HashSet<>(List.of(id1))); } } } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index c1697faf9..4e99161dd 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -18,7 +18,6 @@ package org.traccar.session.cache; import org.traccar.broadcast.BroadcastInterface; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; -import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -224,10 +223,6 @@ public class CacheManager implements BroadcastInterface { } finally { lock.writeLock().unlock(); } - - if (object instanceof Device) { - invalidateDeviceGeofences((Device) object); - } } } @@ -304,8 +299,6 @@ public class CacheManager implements BroadcastInterface { devicePositions.put(deviceId, storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); } - - invalidateDeviceGeofences(device); } } @@ -359,11 +352,4 @@ public class CacheManager implements BroadcastInterface { } } - private void invalidateDeviceGeofences(Device device) { - Position position = getPosition(device.getId()); - if (position != null) { - device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(config, this, position)); - } - } - } -- cgit v1.2.3 From a1ec223a7ee9ff86a881428f787c6f11d532432a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 20:13:45 -0700 Subject: Support from email name (fix #4887) --- src/main/java/org/traccar/database/MailManager.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 0c868e1fc..72b8b72c1 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -31,6 +31,7 @@ import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; +import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; @@ -88,6 +89,10 @@ public final class MailManager { if (from != null) { properties.put("mail.smtp.from", from); } + String fromName = provider.getString("mail.smtp.fromName"); + if (fromName != null) { + properties.put("mail.smtp.fromName", fromName); + } } return properties; } @@ -120,7 +125,16 @@ public final class MailManager { String from = properties.getProperty("mail.smtp.from"); if (from != null) { - message.setFrom(new InternetAddress(from)); + String fromName = properties.getProperty("mail.smtp.fromName"); + if (fromName != null) { + try { + message.setFrom(new InternetAddress(from, fromName)); + } catch (UnsupportedEncodingException e) { + throw new MessagingException("Email address issue"); + } + } else { + message.setFrom(new InternetAddress(from)); + } } message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); -- cgit v1.2.3 From 859b9d4aad68f4dafdee60ff14d3c9c0b32693a0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 07:18:16 -0700 Subject: Ignore own multicast packets --- debug.xml | 5 +++-- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/debug.xml b/debug.xml index debbd06b7..a597d83c5 100644 --- a/debug.xml +++ b/debug.xml @@ -24,7 +24,8 @@ true 6037 - + diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index c4ba0e059..be24989dd 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -167,8 +167,10 @@ public class MulticastBroadcastService implements BroadcastService { while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); - String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); - handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + if (networkInterface.inetAddresses().noneMatch(a -> a.equals(packet.getAddress()))) { + String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + } } publisherSocket = null; socket.leaveGroup(group, networkInterface); -- cgit v1.2.3 From adbeacc62ecb91c94f6cfe7dea8e79b8f5e1c802 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 08:05:10 -0700 Subject: Fix geofenceIds issue (fix #4890) --- src/main/java/org/traccar/model/Device.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 6593c59b0..501c7e1c0 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -17,6 +17,7 @@ package org.traccar.model; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -89,8 +90,8 @@ public class Device extends GroupedModel { } @QueryIgnore - public void setGeofenceIds(List geofenceIds) { - this.geofenceIds = geofenceIds; + public void setGeofenceIds(List geofenceIds) { + this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); } private String phone; -- cgit v1.2.3 From 33733f835e88a62c4a5259ab330723b88037adf1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 09:39:22 -0700 Subject: Simplify attribute check --- src/main/java/org/traccar/BaseProtocolEncoder.java | 2 +- src/main/java/org/traccar/WebDataHandler.java | 2 +- src/main/java/org/traccar/handler/CopyAttributesHandler.java | 3 +-- src/main/java/org/traccar/handler/DistanceHandler.java | 4 ++-- src/main/java/org/traccar/handler/EngineHoursHandler.java | 2 +- src/main/java/org/traccar/handler/FilterHandler.java | 4 ++-- src/main/java/org/traccar/handler/MotionHandler.java | 2 +- src/main/java/org/traccar/handler/events/FuelDropEventHandler.java | 4 ++-- src/main/java/org/traccar/handler/events/IgnitionEventHandler.java | 4 ++-- src/main/java/org/traccar/handler/events/MotionEventHandler.java | 2 +- src/main/java/org/traccar/model/ExtendedModel.java | 4 ++++ src/main/java/org/traccar/notificators/NotificatorFirebase.java | 2 +- src/main/java/org/traccar/notificators/NotificatorPushover.java | 2 +- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/S168ProtocolDecoder.java | 2 +- src/main/java/org/traccar/reports/SummaryReportProvider.java | 3 +-- src/main/java/org/traccar/reports/common/ReportUtils.java | 7 +++---- 18 files changed, 27 insertions(+), 26 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index bc1180a08..9c3934184 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -61,7 +61,7 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter } protected void initDevicePassword(Command command, String defaultPassword) { - if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { + if (!command.hasAttribute(Command.KEY_DEVICE_PASSWORD)) { String password = AttributeUtil.getDevicePassword( cacheManager, command.getDeviceId(), getProtocolName(), defaultPassword); command.set(Command.KEY_DEVICE_PASSWORD, password); diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index d25c4fd3c..d0aa32e53 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -125,7 +125,7 @@ public class WebDataHandler extends BaseDataHandler { } private String calculateStatus(Position position) { - if (position.getAttributes().containsKey(Position.KEY_ALARM)) { + if (position.hasAttribute(Position.KEY_ALARM)) { return "0xF841"; // STATUS_PANIC_ON } else if (position.getSpeed() < 1.0) { return "0xF020"; // STATUS_LOCATION diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 50d36471a..1fa47cfaa 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -46,8 +46,7 @@ public class CopyAttributesHandler extends BaseDataHandler { Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null && attributesString != null) { for (String attribute : attributesString.split("[ ,]")) { - if (last.getAttributes().containsKey(attribute) - && !position.getAttributes().containsKey(attribute)) { + if (last.hasAttribute(attribute) && !position.hasAttribute(attribute)) { position.getAttributes().put(attribute, last.getAttributes().get(attribute)); } } diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index fb82b5d8e..87c4a81c9 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -49,7 +49,7 @@ public class DistanceHandler extends BaseDataHandler { protected Position handlePosition(Position position) { double distance = 0.0; - if (position.getAttributes().containsKey(Position.KEY_DISTANCE)) { + if (position.hasAttribute(Position.KEY_DISTANCE)) { distance = position.getDouble(Position.KEY_DISTANCE); } double totalDistance = 0.0; @@ -57,7 +57,7 @@ public class DistanceHandler extends BaseDataHandler { Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { totalDistance = last.getDouble(Position.KEY_TOTAL_DISTANCE); - if (!position.getAttributes().containsKey(Position.KEY_DISTANCE)) { + if (!position.hasAttribute(Position.KEY_DISTANCE)) { distance = DistanceCalculator.distance( position.getLatitude(), position.getLongitude(), last.getLatitude(), last.getLongitude()); diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index bfffdcb0c..54a1a0c25 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -35,7 +35,7 @@ public class EngineHoursHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - if (!position.getAttributes().containsKey(Position.KEY_HOURS)) { + if (!position.hasAttribute(Position.KEY_HOURS)) { Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { long hours = last.getLong(Position.KEY_HOURS); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 00cbf92a0..0bd57319a 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -103,7 +103,7 @@ public class FilterHandler extends BaseDataHandler { private boolean filterDuplicate(Position position, Position last) { if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) { for (String key : position.getAttributes().keySet()) { - if (!last.getAttributes().containsKey(key)) { + if (!last.hasAttribute(key)) { return false; } } @@ -163,7 +163,7 @@ public class FilterHandler extends BaseDataHandler { if (skipAttributes) { String string = AttributeUtil.lookup(cacheManager, Keys.FILTER_SKIP_ATTRIBUTES, position.getDeviceId()); for (String attribute : string.split("[ ,]")) { - if (position.getAttributes().containsKey(attribute)) { + if (position.hasAttribute(attribute)) { return true; } } diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 7b2c04ecf..25ee615c5 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -35,7 +35,7 @@ public class MotionHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - if (!position.getAttributes().containsKey(Position.KEY_MOTION)) { + if (!position.hasAttribute(Position.KEY_MOTION)) { position.set(Position.KEY_MOTION, position.getSpeed() > speedThreshold); } return position; diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java index 2d105af3e..25ae1fadb 100644 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -53,8 +53,8 @@ public class FuelDropEventHandler extends BaseEventHandler { cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); if (fuelDropThreshold > 0) { Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (position.getAttributes().containsKey(Position.KEY_FUEL_LEVEL) - && lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_FUEL_LEVEL)) { + if (position.hasAttribute(Position.KEY_FUEL_LEVEL) + && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) - position.getDouble(Position.KEY_FUEL_LEVEL); diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 6e411539c..3c5ac3545 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -47,11 +47,11 @@ public class IgnitionEventHandler extends BaseEventHandler { Map result = null; - if (position.getAttributes().containsKey(Position.KEY_IGNITION)) { + if (position.hasAttribute(Position.KEY_IGNITION)) { boolean ignition = position.getBoolean(Position.KEY_IGNITION); Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_IGNITION)) { + if (lastPosition != null && lastPosition.hasAttribute(Position.KEY_IGNITION)) { boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION); if (ignition && !oldIgnition) { diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index bc9d5f722..1be1896ef 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -92,7 +92,7 @@ public class MotionEventHandler extends BaseEventHandler { double distance = PositionUtil.calculateDistance(motionPosition, position, false); Boolean ignition = null; if (tripsConfig.getUseIgnition() - && position.getAttributes().containsKey(Position.KEY_IGNITION)) { + && position.hasAttribute(Position.KEY_IGNITION)) { ignition = position.getBoolean(Position.KEY_IGNITION); } if (newMotion) { diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 8353d0e66..0fa1856d1 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -22,6 +22,10 @@ public class ExtendedModel extends BaseModel { private Map attributes = new LinkedHashMap<>(); + public boolean hasAttribute(String key) { + return attributes.containsKey(key); + } + public Map getAttributes() { return attributes; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 5787b7ef2..17a6735ee 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -69,7 +69,7 @@ public class NotificatorFirebase implements Notificator { @Override public void send(User user, Event event, Position position) { - if (user.getAttributes().containsKey("notificationTokens")) { + if (user.hasAttribute("notificationTokens")) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 32ceae780..671984f86 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -65,7 +65,7 @@ public class NotificatorPushover implements Notificator { public void send(User user, Event event, Position position) { String device = ""; - if (user.getAttributes().containsKey("notificator.pushover.device")) { + if (user.hasAttribute("notificator.pushover.device")) { device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); } diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 0a57087fe..d8a753abe 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -284,7 +284,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { if (hasLocation && position.getFixTime() != null) { positions.add(position); - } else if (position.getAttributes().containsKey(Position.KEY_RESULT)) { + } else if (position.hasAttribute(Position.KEY_RESULT)) { position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); positions.add(position); diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index a2009e1b2..b63bcd0c0 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -202,7 +202,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(alarm.substring(2))); } else if (alarm.startsWith("oil ")) { position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(alarm.substring(4))); - } else if (!position.getAttributes().containsKey(Position.KEY_ALARM) && !alarm.equals("tracker")) { + } else if (!position.hasAttribute(Position.KEY_ALARM) && !alarm.equals("tracker")) { position.set(Position.KEY_EVENT, alarm); } diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index a88bfa65a..cf665c6ba 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -107,7 +107,7 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { position.setNetwork(network); } - if (!position.getAttributes().containsKey(Position.KEY_SATELLITES)) { + if (!position.hasAttribute(Position.KEY_SATELLITES)) { getLastLocation(position, null); } diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 02033b9e5..9415f3e81 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -79,8 +79,7 @@ public class SummaryReportProvider { result.setSpentFuel(reportUtils.calculateFuel(firstPosition, previousPosition)); long durationMilliseconds; - if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) - && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) { + if (firstPosition.hasAttribute(Position.KEY_HOURS) && previousPosition.hasAttribute(Position.KEY_HOURS)) { durationMilliseconds = previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS); result.setEngineHours(durationMilliseconds); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index ce5e3d8d4..253a6a2b6 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -154,9 +154,9 @@ public class ReportUtils { } public String findDriver(Position firstPosition, Position lastPosition) { - if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + if (firstPosition.hasAttribute(Position.KEY_DRIVER_UNIQUE_ID)) { return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + } else if (lastPosition.hasAttribute(Position.KEY_DRIVER_UNIQUE_ID)) { return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); } return null; @@ -298,8 +298,7 @@ public class ReportUtils { stop.setDuration(stopDuration); stop.setSpentFuel(calculateFuel(startStop, endStop)); - if (startStop.getAttributes().containsKey(Position.KEY_HOURS) - && endStop.getAttributes().containsKey(Position.KEY_HOURS)) { + if (startStop.hasAttribute(Position.KEY_HOURS) && endStop.hasAttribute(Position.KEY_HOURS)) { stop.setEngineHours(endStop.getLong(Position.KEY_HOURS) - startStop.getLong(Position.KEY_HOURS)); } -- cgit v1.2.3 From a8e38b74e5fc6789676bf35a9b92594a230e3ad8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 17:31:52 -0700 Subject: Avoid broadcast loops (fix #4894) --- src/main/java/org/traccar/api/BaseObjectResource.java | 6 +++--- .../org/traccar/api/resource/PermissionsResource.java | 2 ++ .../java/org/traccar/api/resource/ServerResource.java | 2 +- .../java/org/traccar/broadcast/BroadcastInterface.java | 3 ++- .../org/traccar/broadcast/MulticastBroadcastService.java | 5 ++++- src/main/java/org/traccar/session/ConnectionManager.java | 1 + src/main/java/org/traccar/session/cache/CacheManager.java | 15 ++++++++++----- 7 files changed, 23 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index d10843917..2a3bbe239 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -71,8 +71,8 @@ public abstract class BaseObjectResource extends BaseResour entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); - cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); - connectionManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); + cacheManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); + connectionManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); @@ -98,7 +98,7 @@ public abstract class BaseObjectResource extends BaseResour storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", "id"))); - cacheManager.updateOrInvalidate(entity); + cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 44fc897ac..d35cb98bb 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -72,6 +72,7 @@ public class PermissionsResource extends BaseResource { checkPermission(permission); storage.addPermission(permission); cacheManager.invalidatePermission( + true, permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), @@ -96,6 +97,7 @@ public class PermissionsResource extends BaseResource { checkPermission(permission); storage.removePermission(permission); cacheManager.invalidatePermission( + true, permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 3e6792f5b..4fc76a0d7 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -77,7 +77,7 @@ public class ServerResource extends BaseResource { storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", "id"))); - cacheManager.updateOrInvalidate(entity); + cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); } diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java index 69e610dc6..dddba68b6 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastInterface.java +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -31,10 +31,11 @@ public interface BroadcastInterface { default void updateEvent(boolean local, long userId, Event event) { } - default void invalidateObject(Class clazz, long id) { + default void invalidateObject(boolean local, Class clazz, long id) { } default void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { } diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index be24989dd..3eafe07d3 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -98,7 +98,7 @@ public class MulticastBroadcastService implements BroadcastService { } @Override - public void invalidateObject(Class clazz, long id) { + public void invalidateObject(boolean local, Class clazz, long id) { BroadcastMessage message = new BroadcastMessage(); message.setChanges(Map.of(Permission.getKey(clazz), id)); sendMessage(message); @@ -106,6 +106,7 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { BroadcastMessage message = new BroadcastMessage(); @@ -137,10 +138,12 @@ public class MulticastBroadcastService implements BroadcastService { if (iterator.hasNext()) { var second = iterator.next(); listeners.forEach(listener -> listener.invalidatePermission( + false, Permission.getKeyClass(first.getKey()), first.getValue(), Permission.getKeyClass(second.getKey()), second.getValue())); } else { listeners.forEach(listener -> listener.invalidateObject( + false, Permission.getKeyClass(first.getKey()), first.getValue())); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 62fdd833b..9888cca2b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -364,6 +364,7 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { if (clazz1.equals(User.class) && clazz2.equals(Device.class)) { diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 4e99161dd..58eb95327 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -188,12 +188,12 @@ public class CacheManager implements BroadcastInterface { } @Override - public void invalidateObject(Class clazz, long id) { + public void invalidateObject(boolean local, Class clazz, long id) { try { var object = storage.getObject(clazz, new Request( new Columns.All(), new Condition.Equals("id", "id", id))); if (object != null) { - updateOrInvalidate(object); + updateOrInvalidate(local, object); } else { invalidate(clazz, id); } @@ -202,8 +202,10 @@ public class CacheManager implements BroadcastInterface { } } - public void updateOrInvalidate(T object) throws StorageException { - broadcastService.invalidateObject(object.getClass(), object.getId()); + public void updateOrInvalidate(boolean local, T object) throws StorageException { + if (local) { + broadcastService.invalidateObject(true, object.getClass(), object.getId()); + } boolean invalidate = false; var before = getObject(object.getClass(), object.getId()); @@ -232,9 +234,12 @@ public class CacheManager implements BroadcastInterface { @Override public void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { - broadcastService.invalidatePermission(clazz1, id1, clazz2, id2); + if (local) { + broadcastService.invalidatePermission(true, clazz1, id1, clazz2, id2); + } try { invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); -- cgit v1.2.3 From f20ab941671e2325140767da0d5c56187941b3e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 17:39:09 -0700 Subject: Handle null status --- src/main/java/org/traccar/model/Device.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 501c7e1c0..f3debd1f2 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -57,7 +57,7 @@ public class Device extends GroupedModel { @QueryIgnore public void setStatus(String status) { - this.status = status.trim(); + this.status = status != null ? status.trim() : null; } private Date lastUpdate; -- cgit v1.2.3 From a9199ab710056dda371aa3dd25cffc225374c0d6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 08:09:16 -0700 Subject: Support AT20 protocol format --- .../java/org/traccar/protocol/TotemProtocolDecoder.java | 14 ++++++++++++-- .../org/traccar/protocol/TotemProtocolDecoderTest.java | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 4f520f360..9d0d794f8 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -140,8 +140,12 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .number("(x{8})") // status .number("(dd)(dd)(dd)") // date (yymmdd) .number("(dd)(dd)(dd)") // time (hhmmss) + .groupBegin() .number("(dd)") // battery .number("(dd)") // external power + .or() + .number("(ddd)") // battery + .groupEnd() .number("(dddd)") // adc 1 .groupBegin() .groupBegin() @@ -166,6 +170,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .number("(d{7})") // odometer .number("(dd)(dd.dddd)([NS])") // latitude .number("(ddd)(dd.dddd)([EW])") // longitude + .number("dddd").optional() // temperature .number("dddd") // serial number .number("xx") // checksum .any() @@ -379,8 +384,13 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.setTime(parser.nextDateTime()); - position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.1); - position.set(Position.KEY_POWER, parser.nextDouble()); + if (parser.hasNext(2)) { + position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.1); + position.set(Position.KEY_POWER, parser.nextDouble()); + } + if (parser.hasNext()) { + position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.01); + } position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); diff --git a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java index 83498b5ac..df5734568 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TotemProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TotemProtocolDecoder(null)); + verifyPosition(decoder, text( + "$$0111AA353081090067318|0804400022070722520240400005B364ED5003107300001.700000002245.3919N10231.6952W000001860E")); + verifyPosition(decoder, text( "$$0112E5864606045334223|201112223514,-68.923106,-22.455926,$Cloud,1738,621,730,12100,0,0,255,0,40,40,0,0,255,|13")); -- cgit v1.2.3 From 34fefbffa49925a5d337ff388fb9db400d707f8b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 16:36:26 -0700 Subject: Null check geofenceIds (fix #4896) --- src/main/java/org/traccar/model/Device.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index f3debd1f2..57ba07624 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -91,7 +91,11 @@ public class Device extends GroupedModel { @QueryIgnore public void setGeofenceIds(List geofenceIds) { - this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); + if (geofenceIds != null) { + this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); + } else { + this.geofenceIds = null; + } } private String phone; -- cgit v1.2.3 From 0bd4c493e9003449457e87ebad6c7016ded71c8d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 17:00:57 -0700 Subject: Add LBS location caching (fix #3790) --- src/main/java/org/traccar/MainModule.java | 5 ++- src/main/java/org/traccar/config/Keys.java | 7 ++++ .../java/org/traccar/handler/GeocoderHandler.java | 8 ++-- .../org/traccar/handler/GeolocationHandler.java | 45 ++++++++++++++++------ src/main/java/org/traccar/model/CellTower.java | 20 ++++++++++ src/main/java/org/traccar/model/Network.java | 22 ++++++++++- .../java/org/traccar/model/WifiAccessPoint.java | 19 ++++++++- 7 files changed, 106 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f60d41d62..b9543af25 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -256,9 +256,10 @@ public class MainModule extends AbstractModule { @Provides public static GeolocationHandler provideGeolocationHandler( - Config config, @Nullable GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { + Config config, @Nullable GeolocationProvider geolocationProvider, CacheManager cacheManager, + StatisticsManager statisticsManager) { if (geolocationProvider != null) { - return new GeolocationHandler(config, geolocationProvider, statisticsManager); + return new GeolocationHandler(config, geolocationProvider, cacheManager, statisticsManager); } return null; } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6f19ee863..2e1a14eaf 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1293,6 +1293,13 @@ public final class Keys { "geolocation.processInvalidPositions", List.of(KeyType.CONFIG)); + /** + * Reuse last geolocation result if network details have not changed. + */ + public static final ConfigKey GEOLOCATION_REUSE = new BooleanConfigKey( + "geolocation.reuse", + List.of(KeyType.CONFIG)); + /** * Default MCC value to use if device doesn't report MCC. */ diff --git a/src/main/java/org/traccar/handler/GeocoderHandler.java b/src/main/java/org/traccar/handler/GeocoderHandler.java index 0248fca05..e4f240a90 100644 --- a/src/main/java/org/traccar/handler/GeocoderHandler.java +++ b/src/main/java/org/traccar/handler/GeocoderHandler.java @@ -35,14 +35,14 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { private final CacheManager cacheManager; private final boolean ignorePositions; private final boolean processInvalidPositions; - private final int geocoderReuseDistance; + private final int reuseDistance; public GeocoderHandler(Config config, Geocoder geocoder, CacheManager cacheManager) { this.geocoder = geocoder; this.cacheManager = cacheManager; ignorePositions = config.getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); - geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); + reuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); } @Override @@ -50,10 +50,10 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { if (message instanceof Position && !ignorePositions) { final Position position = (Position) message; if (processInvalidPositions || position.getValid()) { - if (geocoderReuseDistance != 0) { + if (reuseDistance != 0) { Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && lastPosition.getAddress() != null - && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) { + && position.getDouble(Position.KEY_DISTANCE) <= reuseDistance) { position.setAddress(lastPosition.getAddress()); ctx.fireChannelRead(position); return; diff --git a/src/main/java/org/traccar/handler/GeolocationHandler.java b/src/main/java/org/traccar/handler/GeolocationHandler.java index 0e78322c8..e7389f22d 100644 --- a/src/main/java/org/traccar/handler/GeolocationHandler.java +++ b/src/main/java/org/traccar/handler/GeolocationHandler.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. @@ -25,6 +25,7 @@ import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.geolocation.GeolocationProvider; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; @ChannelHandler.Sharable public class GeolocationHandler extends ChannelInboundHandlerAdapter { @@ -32,14 +33,19 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(GeolocationHandler.class); private final GeolocationProvider geolocationProvider; + private final CacheManager cacheManager; private final StatisticsManager statisticsManager; private final boolean processInvalidPositions; + private final boolean reuse; public GeolocationHandler( - Config config, GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { + Config config, GeolocationProvider geolocationProvider, CacheManager cacheManager, + StatisticsManager statisticsManager) { this.geolocationProvider = geolocationProvider; + this.cacheManager = cacheManager; this.statisticsManager = statisticsManager; - this.processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS); + processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS); + reuse = config.getBoolean(Keys.GEOLOCATION_REUSE); } @Override @@ -48,6 +54,17 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { final Position position = (Position) message; if ((position.getOutdated() || processInvalidPositions && !position.getValid()) && position.getNetwork() != null) { + if (reuse) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + if (lastPosition != null && position.getNetwork().equals(lastPosition.getNetwork())) { + updatePosition( + position, lastPosition.getLatitude(), lastPosition.getLongitude(), + lastPosition.getAccuracy()); + ctx.fireChannelRead(position); + return; + } + } + if (statisticsManager != null) { statisticsManager.registerGeolocationRequest(); } @@ -56,15 +73,7 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { new GeolocationProvider.LocationProviderCallback() { @Override public void onSuccess(double latitude, double longitude, double accuracy) { - position.set(Position.KEY_APPROXIMATE, true); - position.setValid(true); - position.setFixTime(position.getDeviceTime()); - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAccuracy(accuracy); - position.setAltitude(0); - position.setSpeed(0); - position.setCourse(0); + updatePosition(position, latitude, longitude, accuracy); ctx.fireChannelRead(position); } @@ -82,4 +91,16 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { } } + private void updatePosition(Position position, double latitude, double longitude, double accuracy) { + position.set(Position.KEY_APPROXIMATE, true); + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + position.setLatitude(latitude); + position.setLongitude(longitude); + position.setAccuracy(accuracy); + position.setAltitude(0); + position.setSpeed(0); + position.setCourse(0); + } + } diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index 16a28ea79..bebbb2432 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -19,6 +19,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import org.traccar.config.Config; import org.traccar.config.Keys; +import java.util.Objects; + @JsonInclude(JsonInclude.Include.NON_NULL) public class CellTower { @@ -111,4 +113,22 @@ public class CellTower { mobileNetworkCode = Integer.parseInt(operatorString.substring(3)); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CellTower cellTower = (CellTower) o; + return Objects.equals(radioType, cellTower.radioType) + && Objects.equals(cellId, cellTower.cellId) + && Objects.equals(locationAreaCode, cellTower.locationAreaCode) + && Objects.equals(mobileCountryCode, cellTower.mobileCountryCode) + && Objects.equals(mobileNetworkCode, cellTower.mobileNetworkCode) + && Objects.equals(signalStrength, cellTower.signalStrength); + } + + @Override + public int hashCode() { + return Objects.hash(radioType, cellId, locationAreaCode, mobileCountryCode, mobileNetworkCode, signalStrength); + } + } diff --git a/src/main/java/org/traccar/model/Network.java b/src/main/java/org/traccar/model/Network.java index 4d67fc5d8..e565f4f59 100644 --- a/src/main/java/org/traccar/model/Network.java +++ b/src/main/java/org/traccar/model/Network.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. @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import java.util.ArrayList; import java.util.Collection; +import java.util.Objects; @JsonInclude(JsonInclude.Include.NON_NULL) public class Network { @@ -118,4 +119,23 @@ public class Network { wifiAccessPoints.add(wifiAccessPoint); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Network network = (Network) o; + return Objects.equals(homeMobileCountryCode, network.homeMobileCountryCode) + && Objects.equals(homeMobileNetworkCode, network.homeMobileNetworkCode) + && Objects.equals(radioType, network.radioType) + && Objects.equals(carrier, network.carrier) + && Objects.equals(cellTowers, network.cellTowers) + && Objects.equals(wifiAccessPoints, network.wifiAccessPoints); + } + + @Override + public int hashCode() { + return Objects.hash( + homeMobileCountryCode, homeMobileNetworkCode, radioType, carrier, cellTowers, wifiAccessPoints); + } + } diff --git a/src/main/java/org/traccar/model/WifiAccessPoint.java b/src/main/java/org/traccar/model/WifiAccessPoint.java index 87a77f3c0..fa7be8700 100644 --- a/src/main/java/org/traccar/model/WifiAccessPoint.java +++ b/src/main/java/org/traccar/model/WifiAccessPoint.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. @@ -17,6 +17,8 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.Objects; + @JsonInclude(JsonInclude.Include.NON_NULL) public class WifiAccessPoint { @@ -63,4 +65,19 @@ public class WifiAccessPoint { this.channel = channel; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WifiAccessPoint that = (WifiAccessPoint) o; + return Objects.equals(macAddress, that.macAddress) + && Objects.equals(signalStrength, that.signalStrength) + && Objects.equals(channel, that.channel); + } + + @Override + public int hashCode() { + return Objects.hash(macAddress, signalStrength, channel); + } + } -- cgit v1.2.3 From 900601111466aa861db8ae77b71b95aec6c8c82e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 17:04:39 -0700 Subject: Fix code style issues --- src/main/java/org/traccar/model/CellTower.java | 8 ++++++-- src/main/java/org/traccar/model/Network.java | 8 ++++++-- src/main/java/org/traccar/model/WifiAccessPoint.java | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index bebbb2432..355594c64 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -115,8 +115,12 @@ public class CellTower { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } CellTower cellTower = (CellTower) o; return Objects.equals(radioType, cellTower.radioType) && Objects.equals(cellId, cellTower.cellId) diff --git a/src/main/java/org/traccar/model/Network.java b/src/main/java/org/traccar/model/Network.java index e565f4f59..b31c53c38 100644 --- a/src/main/java/org/traccar/model/Network.java +++ b/src/main/java/org/traccar/model/Network.java @@ -121,8 +121,12 @@ public class Network { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Network network = (Network) o; return Objects.equals(homeMobileCountryCode, network.homeMobileCountryCode) && Objects.equals(homeMobileNetworkCode, network.homeMobileNetworkCode) diff --git a/src/main/java/org/traccar/model/WifiAccessPoint.java b/src/main/java/org/traccar/model/WifiAccessPoint.java index fa7be8700..e28c1b935 100644 --- a/src/main/java/org/traccar/model/WifiAccessPoint.java +++ b/src/main/java/org/traccar/model/WifiAccessPoint.java @@ -67,8 +67,12 @@ public class WifiAccessPoint { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } WifiAccessPoint that = (WifiAccessPoint) o; return Objects.equals(macAddress, that.macAddress) && Objects.equals(signalStrength, that.signalStrength) -- cgit v1.2.3 From 204e98895b3cd9a37ceea1760917c07606b36b10 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 18:42:28 -0700 Subject: Migrate SMTP settings --- src/main/java/org/traccar/config/Config.java | 31 ++---- src/main/java/org/traccar/config/Keys.java | 96 ++++++++++++++++++ .../java/org/traccar/database/MailManager.java | 110 ++++++++++----------- .../traccar/notification/PropertiesProvider.java | 27 ++--- 4 files changed, 165 insertions(+), 99 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Config.java b/src/main/java/org/traccar/config/Config.java index 5f95c16d9..c73be6475 100644 --- a/src/main/java/org/traccar/config/Config.java +++ b/src/main/java/org/traccar/config/Config.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. @@ -25,6 +25,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.InvalidPropertiesFormatException; +import java.util.Objects; import java.util.Properties; @Singleton @@ -71,8 +72,7 @@ public class Config { return hasKey(key.getKey()); } - @Deprecated - public boolean hasKey(String key) { + private boolean hasKey(String key) { return useEnvironmentVariables && System.getenv().containsKey(getEnvironmentVariableName(key)) || properties.containsKey(key); } @@ -102,12 +102,7 @@ public class Config { } public boolean getBoolean(ConfigKey key) { - return getBoolean(key.getKey()); - } - - @Deprecated - public boolean getBoolean(String key) { - return Boolean.parseBoolean(getString(key)); + return Boolean.parseBoolean(getString(key.getKey())); } public int getInteger(ConfigKey key) { @@ -116,11 +111,7 @@ public class Config { return Integer.parseInt(value); } else { Integer defaultValue = key.getDefaultValue(); - if (defaultValue != null) { - return defaultValue; - } else { - return 0; - } + return Objects.requireNonNullElse(defaultValue, 0); } } @@ -139,11 +130,7 @@ public class Config { return Long.parseLong(value); } else { Long defaultValue = key.getDefaultValue(); - if (defaultValue != null) { - return defaultValue; - } else { - return 0; - } + return Objects.requireNonNullElse(defaultValue, 0L); } } @@ -153,11 +140,7 @@ public class Config { return Double.parseDouble(value); } else { Double defaultValue = key.getDefaultValue(); - if (defaultValue != null) { - return defaultValue; - } else { - return 0; - } + return Objects.requireNonNullElse(defaultValue, 0.0); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 2e1a14eaf..7ab45312f 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -800,6 +800,102 @@ public final class Keys { List.of(KeyType.CONFIG), "templates"); + /** + * Force SMTP settings from the config file and ignore user attributes. + */ + public static final ConfigKey MAIL_SMTP_IGNORE_USER_CONFIG = new BooleanConfigKey( + "mail.smtp.ignoreUserConfig", + List.of(KeyType.CONFIG)); + + /** + * The SMTP server to connect to. + */ + public static final ConfigKey MAIL_SMTP_HOST = new StringConfigKey( + "mail.smtp.host", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * The SMTP server port to connect. Defaults to 25. + */ + public static final ConfigKey MAIL_SMTP_PORT = new IntegerConfigKey( + "mail.smtp.port", + List.of(KeyType.CONFIG, KeyType.USER), + 25); + + /** + * Email transport protocol. Default value is "smtp". + */ + public static final ConfigKey MAIL_TRANSPORT_PROTOCOL = new StringConfigKey( + "mail.transport.protocol", + List.of(KeyType.CONFIG, KeyType.USER), + "smtp"); + + /** + * If true, enables the use of the STARTTLS command (if supported by the server) to switch the connection to a + * TLS-protected connection before issuing any login commands. + */ + public static final ConfigKey MAIL_SMTP_STARTTLS_ENABLE = new BooleanConfigKey( + "mail.smtp.starttls.enable", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * If true, requires the use of the STARTTLS command. If the server doesn't support the STARTTLS command, or the + * command fails, the connect method will fail. + */ + public static final ConfigKey MAIL_SMTP_STARTTLS_REQUIRED = new BooleanConfigKey( + "mail.smtp.starttls.required", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * If set to true, use SSL to connect and use the SSL port by default. + */ + public static final ConfigKey MAIL_SMTP_SSL_ENABLE = new BooleanConfigKey( + "mail.smtp.ssl.enable", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * If set to "*", all hosts are trusted. If set to a whitespace separated list of hosts, those hosts are trusted. + * Otherwise, trust depends on the certificate the server presents. + */ + public static final ConfigKey MAIL_SMTP_SSL_TRUST = new StringConfigKey( + "mail.smtp.ssl.trust", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * Specifies the SSL protocols that will be enabled for SSL connections. + */ + public static final ConfigKey MAIL_SMTP_SSL_PROTOCOLS = new StringConfigKey( + "mail.smtp.ssl.protocols", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * SMTP connection username. + */ + public static final ConfigKey MAIL_SMTP_USERNAME = new StringConfigKey( + "mail.smtp.username", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * SMTP connection password. + */ + public static final ConfigKey MAIL_SMTP_PASSWORD = new StringConfigKey( + "mail.smtp.password", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * Email address to use for SMTP MAIL command. + */ + public static final ConfigKey MAIL_SMTP_FROM = new StringConfigKey( + "mail.smtp.from", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * The personal name for the email from address. + */ + public static final ConfigKey MAIL_SMTP_FROM_NAME = new StringConfigKey( + "mail.smtp.fromName", + List.of(KeyType.CONFIG, KeyType.USER)); + /** * SMS API service full URL. Enables SMS commands and notifications. */ diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 72b8b72c1..ec1681dcb 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -17,6 +17,8 @@ package org.traccar.database; import org.traccar.config.Config; +import org.traccar.config.ConfigKey; +import org.traccar.config.Keys; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; @@ -37,6 +39,8 @@ import java.util.Properties; public final class MailManager { + private static final String CONTENT_TYPE = "text/html; charset=utf-8"; + private final Config config; private final StatisticsManager statisticsManager; @@ -46,59 +50,48 @@ public final class MailManager { this.statisticsManager = statisticsManager; } - private static Properties getProperties(PropertiesProvider provider) { - Properties properties = new Properties(); - String host = provider.getString("mail.smtp.host"); - if (host != null) { - properties.put("mail.transport.protocol", provider.getString("mail.transport.protocol", "smtp")); - properties.put("mail.smtp.host", host); - properties.put("mail.smtp.port", String.valueOf(provider.getInteger("mail.smtp.port", 25))); - - Boolean starttlsEnable = provider.getBoolean("mail.smtp.starttls.enable"); - if (starttlsEnable != null) { - properties.put("mail.smtp.starttls.enable", String.valueOf(starttlsEnable)); - } - Boolean starttlsRequired = provider.getBoolean("mail.smtp.starttls.required"); - if (starttlsRequired != null) { - properties.put("mail.smtp.starttls.required", String.valueOf(starttlsRequired)); - } - - Boolean sslEnable = provider.getBoolean("mail.smtp.ssl.enable"); - if (sslEnable != null) { - properties.put("mail.smtp.ssl.enable", String.valueOf(sslEnable)); - } - String sslTrust = provider.getString("mail.smtp.ssl.trust"); - if (sslTrust != null) { - properties.put("mail.smtp.ssl.trust", sslTrust); - } + private static void copyBooleanProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + Boolean value = provider.getBoolean(key); + if (value != null) { + properties.put(key.getKey(), String.valueOf(value)); + } + } - String sslProtocols = provider.getString("mail.smtp.ssl.protocols"); - if (sslProtocols != null) { - properties.put("mail.smtp.ssl.protocols", sslProtocols); - } + private static void copyStringProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + String value = provider.getString(key); + if (value != null) { + properties.put(key.getKey(), value); + } + } - String username = provider.getString("mail.smtp.username"); - if (username != null) { - properties.put("mail.smtp.username", username); - } - String password = provider.getString("mail.smtp.password"); - if (password != null) { - properties.put("mail.smtp.password", password); - } - String from = provider.getString("mail.smtp.from"); - if (from != null) { - properties.put("mail.smtp.from", from); - } - String fromName = provider.getString("mail.smtp.fromName"); - if (fromName != null) { - properties.put("mail.smtp.fromName", fromName); - } + private static Properties getProperties(PropertiesProvider provider) { + String host = provider.getString(Keys.MAIL_SMTP_HOST); + if (host != null) { + Properties properties = new Properties(); + + properties.put(Keys.MAIL_TRANSPORT_PROTOCOL.getKey(), provider.getString(Keys.MAIL_TRANSPORT_PROTOCOL)); + properties.put(Keys.MAIL_SMTP_HOST.getKey(), host); + properties.put(Keys.MAIL_SMTP_PORT.getKey(), String.valueOf(provider.getInteger(Keys.MAIL_SMTP_PORT))); + + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_ENABLE); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_REQUIRED); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_SSL_ENABLE); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_TRUST); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_PROTOCOLS); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_USERNAME); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_PASSWORD); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM_NAME); + + return properties; } - return properties; + return null; } public boolean getEmailEnabled() { - return config.hasKey("mail.smtp.host"); + return config.hasKey(Keys.MAIL_SMTP_HOST); } public void sendMessage( @@ -108,24 +101,25 @@ public final class MailManager { public void sendMessage( User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + Properties properties = null; - if (!config.getBoolean("mail.smtp.ignoreUserConfig")) { + if (!config.getBoolean(Keys.MAIL_SMTP_IGNORE_USER_CONFIG)) { properties = getProperties(new PropertiesProvider(user)); } - if (properties == null || !properties.containsKey("mail.smtp.host")) { + if (properties == null) { properties = getProperties(new PropertiesProvider(config)); } - if (!properties.containsKey("mail.smtp.host")) { - throw new RuntimeException("No SMTP configuration found"); + if (properties == null) { + throw new MessagingException("No SMTP configuration found"); } Session session = Session.getInstance(properties); MimeMessage message = new MimeMessage(session); - String from = properties.getProperty("mail.smtp.from"); + String from = properties.getProperty(Keys.MAIL_SMTP_FROM.getKey()); if (from != null) { - String fromName = properties.getProperty("mail.smtp.fromName"); + String fromName = properties.getProperty(Keys.MAIL_SMTP_FROM_NAME.getKey()); if (fromName != null) { try { message.setFrom(new InternetAddress(from, fromName)); @@ -145,21 +139,21 @@ public final class MailManager { Multipart multipart = new MimeMultipart(); BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setContent(body, "text/html; charset=utf-8"); + messageBodyPart.setContent(body, CONTENT_TYPE); multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(attachment); message.setContent(multipart); } else { - message.setContent(body, "text/html; charset=utf-8"); + message.setContent(body, CONTENT_TYPE); } try (Transport transport = session.getTransport()) { statisticsManager.registerMail(); transport.connect( - properties.getProperty("mail.smtp.host"), - properties.getProperty("mail.smtp.username"), - properties.getProperty("mail.smtp.password")); + properties.getProperty(Keys.MAIL_SMTP_HOST.getKey()), + properties.getProperty(Keys.MAIL_SMTP_USERNAME.getKey()), + properties.getProperty(Keys.MAIL_SMTP_PASSWORD.getKey())); transport.sendMessage(message, message.getAllRecipients()); } } diff --git a/src/main/java/org/traccar/notification/PropertiesProvider.java b/src/main/java/org/traccar/notification/PropertiesProvider.java index f0078feef..4ffad432c 100644 --- a/src/main/java/org/traccar/notification/PropertiesProvider.java +++ b/src/main/java/org/traccar/notification/PropertiesProvider.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. @@ -16,6 +16,7 @@ package org.traccar.notification; import org.traccar.config.Config; +import org.traccar.config.ConfigKey; import org.traccar.model.ExtendedModel; public class PropertiesProvider { @@ -32,36 +33,28 @@ public class PropertiesProvider { this.extendedModel = extendedModel; } - public String getString(String key) { + public String getString(ConfigKey key) { if (config != null) { return config.getString(key); } else { - return extendedModel.getString(key); + return extendedModel.getString(key.getKey()); } } - public String getString(String key, String defaultValue) { - String value = getString(key); - if (value == null) { - value = defaultValue; - } - return value; - } - - public int getInteger(String key, int defaultValue) { + public int getInteger(ConfigKey key) { if (config != null) { - return config.getInteger(key, defaultValue); + return config.getInteger(key); } else { - Object result = extendedModel.getAttributes().get(key); + Object result = extendedModel.getAttributes().get(key.getKey()); if (result != null) { return result instanceof String ? Integer.parseInt((String) result) : (Integer) result; } else { - return defaultValue; + return key.getDefaultValue(); } } } - public Boolean getBoolean(String key) { + public Boolean getBoolean(ConfigKey key) { if (config != null) { if (config.hasKey(key)) { return config.getBoolean(key); @@ -69,7 +62,7 @@ public class PropertiesProvider { return null; } } else { - Object result = extendedModel.getAttributes().get(key); + Object result = extendedModel.getAttributes().get(key.getKey()); if (result != null) { return result instanceof String ? Boolean.valueOf((String) result) : (Boolean) result; } else { -- cgit v1.2.3 From 27e8b2f8b24b12ddc4662c5559419d72755bbf08 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 18:50:44 -0700 Subject: Filter for old data (fix #3800) --- src/main/java/org/traccar/config/Keys.java | 12 ++++++++++-- src/main/java/org/traccar/handler/FilterHandler.java | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 7ab45312f..5f31fe99c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1104,13 +1104,21 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Filter records with fix time in future. The values is specified in seconds. Records that have fix time more than - * specified number of seconds later than current server time would be filtered out. + * Filter records with fix time in the future. The value is specified in seconds. Records that have fix time more + * than the specified number of seconds later than current server time would be filtered out. */ public static final ConfigKey FILTER_FUTURE = new LongConfigKey( "filter.future", List.of(KeyType.CONFIG)); + /** + * Filter records with fix time in the past. The value is specified in seconds. Records that have fix time more + * than the specified number of seconds before current server time would be filtered out. + */ + public static final ConfigKey FILTER_PAST = new LongConfigKey( + "filter.past", + List.of(KeyType.CONFIG)); + /** * Filter positions with accuracy less than specified value in meters. */ diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 0bd57319a..37f5cd566 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -47,6 +47,7 @@ public class FilterHandler extends BaseDataHandler { private final boolean filterZero; private final boolean filterDuplicate; private final long filterFuture; + private final long filterPast; private final boolean filterApproximate; private final int filterAccuracy; private final boolean filterStatic; @@ -67,6 +68,7 @@ public class FilterHandler extends BaseDataHandler { filterZero = config.getBoolean(Keys.FILTER_ZERO); filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE); filterFuture = config.getLong(Keys.FILTER_FUTURE) * 1000; + filterPast = config.getLong(Keys.FILTER_PAST) * 1000; filterAccuracy = config.getInteger(Keys.FILTER_ACCURACY); filterApproximate = config.getBoolean(Keys.FILTER_APPROXIMATE); filterStatic = config.getBoolean(Keys.FILTER_STATIC); @@ -116,6 +118,10 @@ public class FilterHandler extends BaseDataHandler { return filterFuture != 0 && position.getFixTime().getTime() > System.currentTimeMillis() + filterFuture; } + private boolean filterPast(Position position) { + return filterPast != 0 && position.getFixTime().getTime() < System.currentTimeMillis() - filterPast; + } + private boolean filterAccuracy(Position position) { return filterAccuracy != 0 && position.getAccuracy() > filterAccuracy; } @@ -185,6 +191,9 @@ public class FilterHandler extends BaseDataHandler { if (filterFuture(position)) { filterType.append("Future "); } + if (filterPast(position)) { + filterType.append("Past "); + } if (filterAccuracy(position)) { filterType.append("Accuracy "); } -- cgit v1.2.3 From 6a39fec53770002149d70ba3b09b8bf1f03a5780 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 07:12:47 -0700 Subject: Remove misused timezone --- src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java index 92dae7285..b07b94e20 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 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,7 +24,6 @@ import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; -import java.util.TimeZone; import java.util.regex.Pattern; public class AustinNbProtocolDecoder extends BaseProtocolDecoder { @@ -64,7 +63,7 @@ public class AustinNbProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS, TimeZone.getDefault().getID())); + position.setTime(parser.nextDateTime()); position.setValid(true); position.setLatitude(Double.parseDouble(parser.next().replace(',', '.'))); -- cgit v1.2.3 From 80bbf6e1b1903ba9218245c4fe94e5b482b59dad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 07:13:21 -0700 Subject: Support ITS custom timezone (fix #4232) --- src/main/java/org/traccar/protocol/ItsProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java index 1ed9a7d8c..8a8d734cf 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java @@ -205,7 +205,8 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.setValid(parser.nextInt() == 1); } - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setTime(parser.nextDateTime( + Parser.DateTimeFormat.DMY_HMS, getTimeZone(deviceSession.getDeviceId()).getID())); if (parser.hasNext()) { position.setValid(parser.next().matches("[1A]")); } -- cgit v1.2.3 From 16e63283a2b64b2e1b490701c219beed653f2b17 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 07:29:55 -0700 Subject: Fix password update --- src/main/java/org/traccar/api/BaseObjectResource.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 2a3bbe239..408594315 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -98,6 +98,10 @@ public abstract class BaseObjectResource extends BaseResour storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + if (entity instanceof User) { + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + } cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); -- cgit v1.2.3 From 159f0ef4861b64085cdd1c1d8d0234f47bc75797 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 08:03:57 -0700 Subject: Update only if password changed --- src/main/java/org/traccar/api/BaseObjectResource.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 408594315..0ec2bfeaa 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -99,8 +99,11 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); if (entity instanceof User) { - storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + User user = (User) entity; + if (user.getHashedPassword() != null) { + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + } } cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); -- cgit v1.2.3 From ca4488bd093d25afa494ab30e117fdef98e20013 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 11:41:53 -0700 Subject: Migrate to Firebase SDK --- build.gradle | 1 + src/main/java/org/traccar/config/Keys.java | 6 +- .../traccar/notificators/NotificatorFirebase.java | 86 +++++++++++----------- .../traccar/notificators/NotificatorTraccar.java | 55 +++++++++++++- 4 files changed, 100 insertions(+), 48 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 8ba907843..675d1490f 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "com.sun.xml.bind:jaxb-impl:3.0.2" implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" + implementation "com.google.firebase:firebase-admin:9.0.0" testImplementation "junit:junit:4.13.2" testImplementation "org.mockito:mockito-core:3.+" } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 5f31fe99c..1217ab94c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -978,10 +978,10 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Firebase server API key for push notifications. + * Firebase service account JSON. */ - public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new StringConfigKey( - "notificator.firebase.key", + public static final ConfigKey NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT = new StringConfigKey( + "notificator.firebase.serviceAccount", List.of(KeyType.CONFIG)); /** diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 17a6735ee..ecf3fbb70 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -16,73 +16,77 @@ */ package org.traccar.notificators; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.AndroidConfig; +import com.google.firebase.messaging.AndroidNotification; +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.Position; import org.traccar.model.User; +import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; +import javax.inject.Singleton; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +@Singleton public class NotificatorFirebase implements Notificator { private final NotificationFormatter notificationFormatter; - private final Client client; - private final String url; - private final String key; + @Inject + public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter) throws IOException { - public static class Notification { - @JsonProperty("title") - private String title; - @JsonProperty("body") - private String body; - @JsonProperty("sound") - private String sound; - } + this.notificationFormatter = notificationFormatter; - public static class Message { - @JsonProperty("registration_ids") - private String[] tokens; - @JsonProperty("notification") - private Notification notification; - } + InputStream serviceAccount = new ByteArrayInputStream( + config.getString(Keys.NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT).getBytes()); - @Inject - public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter, Client client) { - this( - notificationFormatter, client, "https://fcm.googleapis.com/fcm/send", - config.getString(Keys.NOTIFICATOR_FIREBASE_KEY)); - } + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(GoogleCredentials.fromStream(serviceAccount)) + .build(); - protected NotificatorFirebase( - NotificationFormatter notificationFormatter, Client client, String url, String key) { - this.notificationFormatter = notificationFormatter; - this.client = client; - this.url = url; - this.key = key; + FirebaseApp.initializeApp(options); } @Override - public void send(User user, Event event, Position position) { + public void send(User user, Event event, Position position) throws MessageException { 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"; + List registrationTokens = Arrays.asList(user.getString("notificationTokens").split("[, ]")); - Message message = new Message(); - message.tokens = user.getString("notificationTokens").split("[, ]"); - message.notification = notification; + MulticastMessage message = MulticastMessage.builder() + .setNotification(Notification.builder() + .setTitle(shortMessage.getSubject()) + .setBody(shortMessage.getBody()) + .build()) + .setAndroidConfig(AndroidConfig.builder() + .setNotification(AndroidNotification.builder() + .setSound("default") + .build()) + .build()) + .addAllTokens(registrationTokens) + .build(); - client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + try { + FirebaseMessaging.getInstance().sendMulticast(message); + } catch (FirebaseMessagingException e) { + throw new MessageException(e); + } } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 8f1260e96..cb8647335 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -15,20 +15,67 @@ */ package org.traccar.notificators; +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.Position; +import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; -public class NotificatorTraccar extends NotificatorFirebase { +public class NotificatorTraccar implements Notificator { + + private final NotificationFormatter notificationFormatter; + private final Client client; + + private final String url; + private final String key; + + public static class Notification { + @JsonProperty("title") + private String title; + @JsonProperty("body") + private String body; + @JsonProperty("sound") + private String sound; + } + + public static class Message { + @JsonProperty("registration_ids") + private String[] tokens; + @JsonProperty("notification") + private Notification notification; + } @Inject public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { - super( - notificationFormatter, client, "https://www.traccar.org/push/", - config.getString(Keys.NOTIFICATOR_TRACCAR_KEY)); + this.notificationFormatter = notificationFormatter; + this.client = client; + this.url = "http://localhost:3001/push/"; + this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); + } + + @Override + public void send(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"; + + Message message = new Message(); + message.tokens = user.getString("notificationTokens").split("[, ]"); + message.notification = notification; + + client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + } } } -- cgit v1.2.3 From ee30e6e63f110476f557ed4ca8a081eb5b589101 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 20:47:59 -0700 Subject: Parameter to enable protocols (fix #3991) --- src/main/java/org/traccar/ServerManager.java | 18 ++++++++++++++---- src/main/java/org/traccar/config/Keys.java | 10 ++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 8d6e615dc..57afb01fd 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -28,9 +28,12 @@ import java.io.IOException; import java.net.BindException; import java.net.ConnectException; import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @Singleton @@ -44,11 +47,18 @@ public class ServerManager implements LifecycleObject { @Inject public ServerManager( Injector injector, Config config) throws IOException, URISyntaxException, ReflectiveOperationException { + Set enabledProtocols = null; + if (config.hasKey(Keys.PROTOCOLS_ENABLE)) { + enabledProtocols = new HashSet<>(Arrays.asList(config.getString(Keys.PROTOCOLS_ENABLE).split("[, ]"))); + } for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { - if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { - BaseProtocol protocol = (BaseProtocol) injector.getInstance(protocolClass); - connectorList.addAll(protocol.getConnectorList()); - protocolList.put(protocol.getName(), protocol); + String protocolName = BaseProtocol.nameFromClass(protocolClass); + if (enabledProtocols == null || enabledProtocols.contains(protocolName)) { + if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(protocolName))) { + BaseProtocol protocol = (BaseProtocol) injector.getInstance(protocolClass); + connectorList.addAll(protocol.getConnectorList()); + protocolList.put(protocol.getName(), protocol); + } } } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 1217ab94c..2190f82f7 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1210,6 +1210,16 @@ public final class Keys { "time.override", List.of(KeyType.CONFIG)); + /** + * List of protocols to enable. If not specified, Traccar enabled all protocols that have port numbers listed. + * The value is a comma-separated list of protocol names. + * + * Example value: teltonika,osmand + */ + public static final ConfigKey PROTOCOLS_ENABLE = new StringConfigKey( + "protocols.enable", + List.of(KeyType.CONFIG)); + /** * List of protocols for overriding time. If not specified override is applied globally. List consist of protocol * names that can be separated by comma or single space character. -- cgit v1.2.3 From 09a85fa9e43b9781d3d8e12bbbe0ff42a7d02b12 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 08:11:29 -0700 Subject: Support C2Stek variation (fix #4331) --- .../java/org/traccar/protocol/C2stekProtocolDecoder.java | 12 ++++++++---- .../java/org/traccar/protocol/C2stekProtocolDecoderTest.java | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index 42a61ef85..aef158fc7 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -49,10 +49,12 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { .number("(-?d+.d+)#") // altitude .number("(d+)#") // battery .number("d+#") // geo area alarm - .number("(x+)#") // alarm - .number("([01])?") // armed + .number("(x+)") // alarm + .groupBegin() + .number("#([01])?") // armed .number("([01])") // door .number("([01])#") // ignition + .groupEnd("?") .any() .text("$AP") .compile(); @@ -114,8 +116,10 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.set(Position.KEY_ARMED, parser.nextInt() > 0); } - position.set(Position.KEY_DOOR, parser.nextInt() > 0); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + if (parser.hasNext(2)) { + position.set(Position.KEY_DOOR, parser.nextInt() > 0); + position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + } return position; } diff --git a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java index fbb530e7f..28876075d 100644 --- a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class C2stekProtocolDecoderTest extends ProtocolTest { var decoder = inject(new C2stekProtocolDecoder(null)); + verifyPosition(decoder, text( + "PA$012207006145046$D#190607#123157#1#37.947087#023.768669#000.00#314.6#00000.0#4104#000#8$AP")); + verifyPosition(decoder, text( "PA$867965024889327$D#220222#135059#0#+37.98995#+23.85141#0.00#69.2#0.0#0000#000#8#00#sz-w1001#B2600$AP")); -- cgit v1.2.3 From 6713984001dbdd838d6d8dabcfd252e768f018c4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 18:45:33 -0700 Subject: Fix group caching --- src/main/java/org/traccar/session/cache/CacheManager.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 58eb95327..0865b2647 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -23,6 +23,7 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; +import org.traccar.model.Group; import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; @@ -52,6 +53,7 @@ import java.util.stream.Collectors; @Singleton public class CacheManager implements BroadcastInterface { + private static final int GROUP_DEPTH_LIMIT = 3; private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); @@ -276,6 +278,17 @@ public class CacheManager implements BroadcastInterface { if (device != null) { addObject(deviceId, device); + int groupDepth = 0; + long groupId = device.getGroupId(); + while (groupDepth < GROUP_DEPTH_LIMIT && groupId > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", groupId))); + links.computeIfAbsent(Group.class, k -> new LinkedList<>()).add(group.getId()); + addObject(deviceId, group); + groupId = group.getGroupId(); + groupDepth += 1; + } + for (Class clazz : CLASSES) { var objects = storage.getObjects(clazz, new Request( new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); -- cgit v1.2.3 From cf2583cec5f6b9c92730bdcdc5805944ff0bfa59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 09:08:01 -0700 Subject: OsmAnd missing coordinates (fix #4420) --- .../org/traccar/protocol/OsmAndProtocolDecoder.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index 3574dd2a3..5f8e7424b 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -59,6 +59,8 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { position.setValid(true); Network network = new Network(); + Double latitude = null; + Double longitude = null; for (Map.Entry> entry : params.entrySet()) { for (String value : entry.getValue()) { @@ -92,15 +94,15 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { } break; case "lat": - position.setLatitude(Double.parseDouble(value)); + latitude = Double.parseDouble(value); break; case "lon": - position.setLongitude(Double.parseDouble(value)); + longitude = Double.parseDouble(value); break; case "location": String[] location = value.split(","); - position.setLatitude(Double.parseDouble(location[0])); - position.setLongitude(Double.parseDouble(location[1])); + latitude = Double.parseDouble(location[0]); + longitude = Double.parseDouble(location[1]); break; case "cell": String[] cell = value.split(","); @@ -170,7 +172,10 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { position.setNetwork(network); } - if (position.getLatitude() == 0 && position.getLongitude() == 0) { + if (latitude != null && longitude != null) { + position.setLatitude(latitude); + position.setLongitude(longitude); + } else { getLastLocation(position, position.getDeviceTime()); } -- cgit v1.2.3 From 8bc3c8c7d2c762ec00bfb1960dcd02171b7312a6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 16:52:31 -0700 Subject: Disable email change (fix #3878) --- schema/changelog-5.3.xml | 21 +++++++++++++++++++++ schema/changelog-master.xml | 1 + .../traccar/api/security/PermissionsService.java | 6 +++++- src/main/java/org/traccar/model/Server.java | 11 +++++++++++ src/main/java/org/traccar/model/User.java | 15 +++++++++++++-- .../java/org/traccar/model/UserRestrictions.java | 1 + 6 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 schema/changelog-5.3.xml (limited to 'src/main/java/org') diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml new file mode 100644 index 000000000..b574a67d2 --- /dev/null +++ b/schema/changelog-5.3.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 83a1ac865..cea15397d 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -33,5 +33,6 @@ + diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index a3e7a182f..a494c0257 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -166,13 +166,17 @@ public class PermissionsService { || before.getDeviceReadonly() != after.getDeviceReadonly() || before.getDisabled() != after.getDisabled() || before.getLimitCommands() != after.getLimitCommands() - || before.getDisableReports() != after.getDisableReports()) { + || before.getDisableReports() != after.getDisableReports() + || before.getFixedEmail() != after.getFixedEmail()) { if (userId == after.getId()) { checkAdmin(userId); } else { checkUser(userId, after.getId()); } } + if (before.getFixedEmail() && !before.getEmail().equals(after.getEmail())) { + checkAdmin(userId); + } } public void checkPermission( diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index e39da1b16..9e248e7bb 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -177,6 +177,17 @@ public class Server extends ExtendedModel implements UserRestrictions { this.disableReports = disableReports; } + private boolean fixedEmail; + + @Override + public boolean getFixedEmail() { + return fixedEmail; + } + + public void setFixedEmail(boolean fixedEmail) { + this.fixedEmail = fixedEmail; + } + private String poiLayer; public String getPoiLayer() { diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 9dd84ad14..0aa67168f 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -232,8 +232,6 @@ public class User extends ExtendedModel implements UserRestrictions { this.limitCommands = limitCommands; } - private String poiLayer; - private boolean disableReports; @Override @@ -245,6 +243,19 @@ public class User extends ExtendedModel implements UserRestrictions { this.disableReports = disableReports; } + private boolean fixedEmail; + + @Override + public boolean getFixedEmail() { + return fixedEmail; + } + + public void setFixedEmail(boolean fixedEmail) { + this.fixedEmail = fixedEmail; + } + + private String poiLayer; + public String getPoiLayer() { return poiLayer; } diff --git a/src/main/java/org/traccar/model/UserRestrictions.java b/src/main/java/org/traccar/model/UserRestrictions.java index 2e4e5e363..1fcc5682e 100644 --- a/src/main/java/org/traccar/model/UserRestrictions.java +++ b/src/main/java/org/traccar/model/UserRestrictions.java @@ -20,4 +20,5 @@ public interface UserRestrictions { boolean getDeviceReadonly(); boolean getLimitCommands(); boolean getDisableReports(); + boolean getFixedEmail(); } -- cgit v1.2.3 From eb79bc251669ed8d107aaf1e2a6beeb0743eacf7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 17:08:52 -0700 Subject: Improve event type order --- .../traccar/api/resource/NotificationResource.java | 33 +++++++++++----------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index a42de687d..2e4ad12f3 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -15,22 +15,6 @@ */ package org.traccar.api.resource; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.ExtendedObjectResource; @@ -42,6 +26,21 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.storage.StorageException; +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + @Path("notifications") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -59,7 +58,7 @@ public class NotificationResource extends ExtendedObjectResource { @GET @Path("types") public Collection get() { - Set types = new HashSet<>(); + List types = new LinkedList<>(); Field[] fields = Event.class.getDeclaredFields(); for (Field field : fields) { if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { -- cgit v1.2.3 From a61e08cb47b8294bf639ebdc0916ead031e92827 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 18:25:49 -0700 Subject: Add media events (fix #3863) --- src/main/java/org/traccar/BasePipelineFactory.java | 2 + .../traccar/handler/events/BaseEventHandler.java | 2 +- .../traccar/handler/events/MediaEventHandler.java | 47 ++++++++++++++++++++++ src/main/java/org/traccar/model/Event.java | 3 +- templates/full/media.vm | 11 +++++ templates/short/media.vm | 2 + 6 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/traccar/handler/events/MediaEventHandler.java create mode 100644 templates/full/media.vm create mode 100644 templates/short/media.vm (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 915c3f7ea..fb48f81d1 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -49,6 +49,7 @@ 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.MediaEventHandler; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; @@ -141,6 +142,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { ComputedAttributesHandler.class, WebDataHandler.class, DefaultDataHandler.class, + MediaEventHandler.class, CommandResultEventHandler.class, OverspeedEventHandler.class, BehaviorEventHandler.class, diff --git a/src/main/java/org/traccar/handler/events/BaseEventHandler.java b/src/main/java/org/traccar/handler/events/BaseEventHandler.java index f7199f6dc..271aaa35d 100644 --- a/src/main/java/org/traccar/handler/events/BaseEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BaseEventHandler.java @@ -36,7 +36,7 @@ public abstract class BaseEventHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { Map events = analyzePosition(position); - if (events != null) { + if (events != null && !events.isEmpty()) { notificationManager.updateEvents(events); } return position; diff --git a/src/main/java/org/traccar/handler/events/MediaEventHandler.java b/src/main/java/org/traccar/handler/events/MediaEventHandler.java new file mode 100644 index 000000000..5b9013fad --- /dev/null +++ b/src/main/java/org/traccar/handler/events/MediaEventHandler.java @@ -0,0 +1,47 @@ +/* + * 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.handler.events; + +import io.netty.channel.ChannelHandler; +import org.traccar.model.Event; +import org.traccar.model.Position; + +import javax.inject.Inject; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@ChannelHandler.Sharable +public class MediaEventHandler extends BaseEventHandler { + + @Inject + public MediaEventHandler() { + } + + @Override + protected Map analyzePosition(Position position) { + return Stream.of(Position.KEY_IMAGE, Position.KEY_VIDEO, Position.KEY_AUDIO) + .filter(position::hasAttribute) + .map(type -> { + Event event = new Event(Event.TYPE_MEDIA, position); + event.set("media", type); + event.set("file", position.getString(type)); + return event; + }) + .collect(Collectors.toMap(event -> event, event -> position)); + } + +} diff --git a/src/main/java/org/traccar/model/Event.java b/src/main/java/org/traccar/model/Event.java index 6e3953fda..f00a0e5f1 100644 --- a/src/main/java/org/traccar/model/Event.java +++ b/src/main/java/org/traccar/model/Event.java @@ -62,10 +62,9 @@ public class Event extends Message { public static final String TYPE_IGNITION_OFF = "ignitionOff"; public static final String TYPE_MAINTENANCE = "maintenance"; - public static final String TYPE_TEXT_MESSAGE = "textMessage"; - public static final String TYPE_DRIVER_CHANGED = "driverChanged"; + public static final String TYPE_MEDIA = "media"; private Date eventTime; diff --git a/templates/full/media.vm b/templates/full/media.vm new file mode 100644 index 000000000..6651deffc --- /dev/null +++ b/templates/full/media.vm @@ -0,0 +1,11 @@ +#set($subject = "$device.name: media file received") + + + +Device: $device.name
+Type: $event.getString("media")
+File: $event.getString("file")
+Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
+Link: $webUrl?eventId=$event.id + + diff --git a/templates/short/media.vm b/templates/short/media.vm new file mode 100644 index 000000000..783636f3f --- /dev/null +++ b/templates/short/media.vm @@ -0,0 +1,2 @@ +#set($subject = "$device.name: media file received") +$device.name $event.getString("media") received: $event.getString("file") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) -- cgit v1.2.3 From c4509720c5dab9d7ba17dd6e89f0d846052b0c39 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 20:47:11 -0700 Subject: Reset start on restart --- src/main/java/org/traccar/Main.java | 6 ++++ .../org/traccar/broadcast/BroadcastService.java | 1 + .../broadcast/MulticastBroadcastService.java | 5 ++++ .../traccar/broadcast/NullBroadcastService.java | 5 ++++ .../java/org/traccar/helper/model/DeviceUtil.java | 33 ++++++++++++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 src/main/java/org/traccar/helper/model/DeviceUtil.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 6a968ac7e..e34fbb72a 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -20,8 +20,10 @@ import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; +import org.traccar.helper.model.DeviceUtil; import org.traccar.schedule.ScheduleManager; import org.traccar.storage.DatabaseModule; +import org.traccar.storage.Storage; import org.traccar.web.WebModule; import org.traccar.web.WebServer; @@ -120,6 +122,10 @@ public final class Main { LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); + if (injector.getInstance(BroadcastService.class).singleInstance()) { + DeviceUtil.resetStatus(injector.getInstance(Storage.class)); + } + var services = Stream.of( ServerManager.class, WebServer.class, ScheduleManager.class, BroadcastService.class) .map(injector::getInstance) diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java index 8a2e4bafc..a86c43b5b 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastService.java +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -18,5 +18,6 @@ package org.traccar.broadcast; import org.traccar.LifecycleObject; public interface BroadcastService extends LifecycleObject, BroadcastInterface { + boolean singleInstance(); void registerListener(BroadcastInterface listener); } diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 3eafe07d3..be65b7826 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -70,6 +70,11 @@ public class MulticastBroadcastService implements BroadcastService { group = new InetSocketAddress(address, port); } + @Override + public boolean singleInstance() { + return false; + } + @Override public void registerListener(BroadcastInterface listener) { listeners.add(listener); diff --git a/src/main/java/org/traccar/broadcast/NullBroadcastService.java b/src/main/java/org/traccar/broadcast/NullBroadcastService.java index 3f41299db..f95037990 100644 --- a/src/main/java/org/traccar/broadcast/NullBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/NullBroadcastService.java @@ -17,6 +17,11 @@ package org.traccar.broadcast; public class NullBroadcastService implements BroadcastService { + @Override + public boolean singleInstance() { + return true; + } + @Override public void registerListener(BroadcastInterface listener) { } diff --git a/src/main/java/org/traccar/helper/model/DeviceUtil.java b/src/main/java/org/traccar/helper/model/DeviceUtil.java new file mode 100644 index 000000000..597078caf --- /dev/null +++ b/src/main/java/org/traccar/helper/model/DeviceUtil.java @@ -0,0 +1,33 @@ +/* + * 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.helper.model; + +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; + +public final class DeviceUtil { + + private DeviceUtil() { + } + + public static void resetStatus(Storage storage) throws StorageException { + storage.updateObject(new Device(), new Request(new Columns.Include("status"))); + } + +} -- cgit v1.2.3 From b8ef27e67a687c27520f7a99640278f8607cdc0b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 08:09:23 -0700 Subject: Fix push notifications --- src/main/java/org/traccar/notificators/NotificatorTraccar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index cb8647335..123b16ad8 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -55,7 +55,7 @@ public class NotificatorTraccar implements Notificator { public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { this.notificationFormatter = notificationFormatter; this.client = client; - this.url = "http://localhost:3001/push/"; + this.url = "https://www.traccar.org/push/"; this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); } -- cgit v1.2.3 From 4d37fc1ec3c4d3ba8e9421df08bb40979b19b5db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 16:22:33 -0700 Subject: Fix get manager users --- src/main/java/org/traccar/api/resource/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 1bb399437..dd71de4c6 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -54,8 +54,8 @@ public class UserResource extends BaseObjectResource { @GET public Collection get(@QueryParam("userId") long userId) throws StorageException { - permissionsService.checkUser(getUserId(), userId); if (userId > 0) { + permissionsService.checkUser(getUserId(), userId); return storage.getObjects(baseClass, new Request( new Columns.All(), new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); -- cgit v1.2.3 From d75bda2f95081e49272d9f6cadd89b1ba398f888 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 16:32:12 -0700 Subject: Better ADC decoding (fix #4899) --- .../org/traccar/protocol/MeitrackProtocolDecoder.java | 15 +++++++-------- .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 4 ++++ 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 87459d3fc..88b7d12c8 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -211,11 +211,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { switch (deviceModel.toUpperCase()) { case "MVT340": case "MVT380": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.0 * 2.0 / 1024.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.0 * 2.0 / 1024.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.0 * 16.0 / 1024.0); break; case "MT90": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0)); break; case "T1": @@ -225,19 +225,18 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case "MVT800": case "TC68": case "TC68S": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.3 * 16.0 / 4096.0); break; case "T311": case "T322X": case "T333": case "T355": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) / 100.0); - position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); - break; + case "T366": + case "T366G": default: - position.set(Position.KEY_BATTERY, parser.nextHexInt(0)); - position.set(Position.KEY_POWER, parser.nextHexInt(0)); + position.set(Position.KEY_BATTERY, parser.nextHexInt() / 100.0); + position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); break; } diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index d4ecae10a..09ab0440d 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "$$F160,861412043027965,AAA,22,45.499458,-82.493581,220718171428,V,0,0,0,0,0.0,0,227940,119812,302|220|D8D6|086E1B2B,0000,0000|0000|0000|0191|0573,,,3,,002134,0,0*FA"), + Position.KEY_POWER, 13.95); + verifyPositions(decoder, binary( "2424423233392c3836323039303035303030373436352c4343452c0100000003004300130006050006000700140015801b00080800000900000a00000b0000165105198d011a630540160005024c5e910103590bfe0204922153290c6b2501000dd5b50200004300130006050006000700140015011b00080800000900000a00000b0000165005198d011a630540010005024c5e910103590bfe0204932153290c6b2501000dd6b50200004300130006050006000700140015011b00080800000900000a00000b0000165205198d011a630540230005024c5e910103590bfe0204942153290c6b2501000dd7b50200002a43330d0a")); -- cgit v1.2.3 From 35070c85e26fe75e73315506b8cae3360f79d12e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 18:45:02 -0700 Subject: Add coordinates validation --- src/main/java/org/traccar/model/Position.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index d6c985458..2b743433a 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -227,7 +227,9 @@ public class Position extends Message { } public void setLatitude(double latitude) { - this.latitude = latitude; + if (latitude >= -90 && latitude <= 90) { + this.latitude = latitude; + } } private double longitude; @@ -237,7 +239,9 @@ public class Position extends Message { } public void setLongitude(double longitude) { - this.longitude = longitude; + if (longitude >= -180 && longitude <= 180) { + this.longitude = longitude; + } } private double altitude; // value in meters -- cgit v1.2.3 From 482876a5d8f4ba2e749aa5b39c29cd07589f7bcc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Jul 2022 16:55:02 -0700 Subject: Add Xexun2 dismantle alarm --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 501897715..a572f8622 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -67,6 +67,9 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(value, 0)) { return Position.ALARM_SOS; } + if (BitUtil.check(value, 1)) { + return Position.ALARM_REMOVING; + } if (BitUtil.check(value, 15)) { return Position.ALARM_FALL_DOWN; } -- cgit v1.2.3 From d42f935e4119fb87002b8b275c4237290ef7f12b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Jul 2022 18:21:31 -0700 Subject: Fix duplicate notifications --- src/main/java/org/traccar/session/cache/CacheManager.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 0865b2647..07f27d776 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -42,6 +42,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -65,7 +66,7 @@ public class CacheManager implements BroadcastInterface { private final Map deviceCache = new HashMap<>(); private final Map deviceReferences = new HashMap<>(); - private final Map, List>> deviceLinks = new HashMap<>(); + private final Map, Set>> deviceLinks = new HashMap<>(); private final Map devicePositions = new HashMap<>(); private Server server; @@ -271,7 +272,7 @@ public class CacheManager implements BroadcastInterface { } private void unsafeAddDevice(long deviceId) throws StorageException { - Map, List> links = new HashMap<>(); + Map, Set> links = new HashMap<>(); Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.Equals("id", "id", deviceId))); @@ -283,7 +284,7 @@ public class CacheManager implements BroadcastInterface { while (groupDepth < GROUP_DEPTH_LIMIT && groupId > 0) { Group group = storage.getObject(Group.class, new Request( new Columns.All(), new Condition.Equals("id", "id", groupId))); - links.computeIfAbsent(Group.class, k -> new LinkedList<>()).add(group.getId()); + links.computeIfAbsent(Group.class, k -> new LinkedHashSet<>()).add(group.getId()); addObject(deviceId, group); groupId = group.getGroupId(); groupDepth += 1; @@ -292,13 +293,13 @@ public class CacheManager implements BroadcastInterface { for (Class clazz : CLASSES) { var objects = storage.getObjects(clazz, new Request( new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); - links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); + links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toSet())); objects.forEach(object -> addObject(deviceId, object)); } var users = storage.getObjects(User.class, new Request( new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); - links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); + links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toSet())); for (var user : users) { addObject(deviceId, user); var notifications = storage.getObjects(Notification.class, new Request( @@ -306,7 +307,7 @@ public class CacheManager implements BroadcastInterface { notifications.stream() .filter(Notification::getAlways) .forEach(object -> { - links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()).add(object.getId()); addObject(deviceId, object); }); } -- cgit v1.2.3 From eb8d5c2d83a6aa91e0932382a852a3f4aca33120 Mon Sep 17 00:00:00 2001 From: Luiz Kill Date: Thu, 21 Jul 2022 13:55:55 -0300 Subject: Adds Pushover user attributes The Pushover integration doesn't allow messages to be delivered per-user, since the NOTIFICATOR_PUSHOVER_USER config is single for the whole instance. --- .../traccar/notificators/NotificatorPushover.java | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 671984f86..0604c49f3 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -56,25 +56,24 @@ public class NotificatorPushover implements Notificator { url = "https://api.pushover.net/1/messages.json"; token = config.getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); user = config.getString(Keys.NOTIFICATOR_PUSHOVER_USER); - if (token == null || user == null) { - throw new RuntimeException("Pushover token or user missing"); - } } @Override public void send(User user, Event event, Position position) { - - String device = ""; - if (user.hasAttribute("notificator.pushover.device")) { - device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); - } - var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); Message message = new Message(); message.token = token; - message.user = this.user; - message.device = device; + + message.user = user.getString("pushoverUserKey"); + if (message.user == null) { + message.user = this.user; + } + + if (user.hasAttribute("pushoverDeviceNames")) { + message.device = user.getString("pushoverDeviceNames").replaceAll(" *, *", ","); + } + message.title = shortMessage.getSubject(); message.message = shortMessage.getBody(); -- cgit v1.2.3 From ea68646e6572945db82bfdf8e732957492e19b03 Mon Sep 17 00:00:00 2001 From: Luiz Kill Date: Thu, 21 Jul 2022 14:12:50 -0300 Subject: Fixes trailing spaces issue --- src/main/java/org/traccar/notificators/NotificatorPushover.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 0604c49f3..105cb27f0 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -64,7 +64,7 @@ public class NotificatorPushover implements Notificator { Message message = new Message(); message.token = token; - + message.user = user.getString("pushoverUserKey"); if (message.user == null) { message.user = this.user; -- cgit v1.2.3 From bf9b8c9562587476a919e095a4adc6c00bb2cba8 Mon Sep 17 00:00:00 2001 From: stefanclark Date: Thu, 21 Jul 2022 21:21:13 +0100 Subject: Update Xexun2ProtocolDecoder.java --- .../java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index a572f8622..42fa7d8f2 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -176,7 +176,19 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.setLongitude(convertCoordinate(buf.readDouble())); position.setLatitude(convertCoordinate(buf.readDouble())); - + } + if (BitUtil.check(positionMask, 7)) { + buf.skipBytes(2); // length = 30 + buf.skipBytes(1); // marker = 'G' + buf.skipBytes(2); // length = 27 + position.setLongitude(convertCoordinate(buf.readDouble())); + position.setLatitude(convertCoordinate(buf.readDouble())); + position.setValid(buf.readUnsignedByte()>0); // 0=invalid,1=normal,2=sub-meter,3=differential + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + buf.skipBytes(1); // SNR + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort() * 0.1); + position.setAltitude(buf.readFloat()); } } if (BitUtil.check(mask, 3)) { -- cgit v1.2.3 From df974772a6cab1f1bdbad4c6b19e150c2ca3ccf6 Mon Sep 17 00:00:00 2001 From: stefanclark Date: Thu, 21 Jul 2022 21:56:49 +0100 Subject: Update Xexun2ProtocolDecoder.java --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 42fa7d8f2..47d86aeb1 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -183,7 +183,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(2); // length = 27 position.setLongitude(convertCoordinate(buf.readDouble())); position.setLatitude(convertCoordinate(buf.readDouble())); - position.setValid(buf.readUnsignedByte()>0); // 0=invalid,1=normal,2=sub-meter,3=differential + position.setValid(buf.readUnsignedByte() > 0); // 0=invalid,1=normal,2=sub-meter,3=differential position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); buf.skipBytes(1); // SNR position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); -- cgit v1.2.3 From c85bcf1966e690d8af56d0eff51dbae5c025340e Mon Sep 17 00:00:00 2001 From: stefanclark Date: Thu, 21 Jul 2022 22:30:46 +0100 Subject: Update Xexun2ProtocolDecoder.java --- .../traccar/protocol/Xexun2ProtocolDecoder.java | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 47d86aeb1..3f37d7cac 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -178,17 +178,25 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(convertCoordinate(buf.readDouble())); } if (BitUtil.check(positionMask, 7)) { - buf.skipBytes(2); // length = 30 - buf.skipBytes(1); // marker = 'G' - buf.skipBytes(2); // length = 27 - position.setLongitude(convertCoordinate(buf.readDouble())); - position.setLatitude(convertCoordinate(buf.readDouble())); - position.setValid(buf.readUnsignedByte() > 0); // 0=invalid,1=normal,2=sub-meter,3=differential - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - buf.skipBytes(1); // SNR - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.setCourse(buf.readUnsignedShort() * 0.1); - position.setAltitude(buf.readFloat()); + if (buf.readUnsignedShort() > 0) { + if (buf.readByte() != 'G') { + buf.skipBytes(buf.readUnsignedShort()); + } else { + int gpsDataLen = buf.readUnsignedShort(); + if (gpsDataLen != 27) { + buf.skipBytes(gpsDataLen); + } else { + position.setLongitude(convertCoordinate(buf.readDouble())); + position.setLatitude(convertCoordinate(buf.readDouble())); + position.setValid(buf.readUnsignedByte() > 0); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + buf.readUnsignedByte(1); // satellite signal to noise ratio + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort() * 0.1); + position.setAltitude(buf.readFloat()); + } + } + } } } if (BitUtil.check(mask, 3)) { -- cgit v1.2.3 From 1b07425955baf2c37216a05a0fdf6afe6258f6d7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 15:38:31 -0700 Subject: Add Arknav UDP support (fix #4708) --- src/main/java/org/traccar/protocol/ArknavProtocol.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index ed38f26d7..4f443aa3a 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 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. @@ -38,6 +38,15 @@ public class ArknavProtocol extends BaseProtocol { pipeline.addLast(new ArknavProtocolDecoder(ArknavProtocol.this)); } }); + addServer(new TrackerServer(config, getName(), true) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new ArknavProtocolDecoder(ArknavProtocol.this)); + } + }); + } } -- cgit v1.2.3 From 89a32633c1bd9119990b7b9070a1ba04e1eb0ea4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 18:34:33 -0700 Subject: Remove double assignment --- src/main/java/org/traccar/protocol/UproProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index bdc6bf24e..f23274a8f 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -67,7 +67,6 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setValid(true); position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); -- cgit v1.2.3 From 033e50725806fdd5597e37a24eff763800e1cdfa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 18:36:12 -0700 Subject: Fix validity decoding --- src/main/java/org/traccar/protocol/UproProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index f23274a8f..ed714e464 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -71,7 +71,7 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); int flags = parser.nextInt(0); - position.setValid(BitUtil.check(flags, 0)); + position.setValid(!BitUtil.check(flags, 0)); if (!BitUtil.check(flags, 1)) { position.setLatitude(-position.getLatitude()); } -- cgit v1.2.3 From 4a10f75f016af996bd15e90101f0d20e4d61e083 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 22 Jul 2022 17:33:40 -0700 Subject: Add device expiration (fix #3056, fix #3529) --- schema/changelog-5.3.xml | 4 +++ .../org/traccar/api/security/LoginService.java | 7 +--- src/main/java/org/traccar/model/Device.java | 16 ++++++++- src/main/java/org/traccar/model/Disableable.java | 39 ++++++++++++++++++++++ src/main/java/org/traccar/model/User.java | 6 +++- .../org/traccar/session/ConnectionManager.java | 6 ++-- 6 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/traccar/model/Disableable.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index b574a67d2..063046ce9 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -16,6 +16,10 @@ + + + + diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 9938cf6dc..104a6fac3 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -83,12 +83,7 @@ public class LoginService { if (user == null) { throw new SecurityException("Unknown account"); } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } + user.checkDisabled(); } } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 57ba07624..f21e5ca84 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -23,7 +23,7 @@ import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @StorageName("tc_devices") -public class Device extends GroupedModel { +public class Device extends GroupedModel implements Disableable { private String name; @@ -140,12 +140,26 @@ public class Device extends GroupedModel { private boolean disabled; + @Override public boolean getDisabled() { return disabled; } + @Override public void setDisabled(boolean disabled) { this.disabled = disabled; } + private Date expirationTime; + + @Override + public Date getExpirationTime() { + return expirationTime; + } + + @Override + public void setExpirationTime(Date expirationTime) { + this.expirationTime = expirationTime; + } + } diff --git a/src/main/java/org/traccar/model/Disableable.java b/src/main/java/org/traccar/model/Disableable.java new file mode 100644 index 000000000..1145d6279 --- /dev/null +++ b/src/main/java/org/traccar/model/Disableable.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.model; + +import java.util.Date; + +public interface Disableable { + + boolean getDisabled(); + + void setDisabled(boolean disabled); + + Date getExpirationTime(); + + void setExpirationTime(Date expirationTime); + + default void checkDisabled() throws SecurityException { + if (getDisabled()) { + throw new SecurityException(getClass().getSimpleName() + " is disabled"); + } + if (getExpirationTime() != null && System.currentTimeMillis() > getExpirationTime().getTime()) { + throw new SecurityException(getClass().getSimpleName() + " has expired"); + } + } + +} diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 0aa67168f..3db20c753 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -24,7 +24,7 @@ import org.traccar.storage.StorageName; import java.util.Date; @StorageName("tc_users") -public class User extends ExtendedModel implements UserRestrictions { +public class User extends ExtendedModel implements UserRestrictions, Disableable { private String name; @@ -155,20 +155,24 @@ public class User extends ExtendedModel implements UserRestrictions { private boolean disabled; + @Override public boolean getDisabled() { return disabled; } + @Override public void setDisabled(boolean disabled) { this.disabled = disabled; } private Date expirationTime; + @Override public Date getExpirationTime() { return expirationTime; } + @Override public void setExpirationTime(Date expirationTime) { this.expirationTime = expirationTime; } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 9888cca2b..2d183ee22 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -136,7 +136,9 @@ public class ConnectionManager implements BroadcastInterface { device = addUnknownDevice(uniqueIds[0]); } - if (device != null && !device.getDisabled()) { + if (device != null) { + device.checkDisabled(); + DeviceSession oldSession = sessionsByDeviceId.remove(device.getId()); if (oldSession != null) { Endpoint oldEndpoint = new Endpoint(oldSession.getChannel(), oldSession.getRemoteAddress()); @@ -160,7 +162,7 @@ public class ConnectionManager implements BroadcastInterface { return deviceSession; } else { - LOGGER.warn((device == null ? "Unknown" : "Disabled") + " device - " + String.join(" ", uniqueIds) + LOGGER.warn("Unknown device - " + String.join(" ", uniqueIds) + " (" + ((InetSocketAddress) remoteAddress).getHostString() + ")"); return null; } -- cgit v1.2.3 From 0242c8c9a2983ed2e082bb64d7941b4d345aa734 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 23 Jul 2022 08:28:00 +0000 Subject: Added test csse & updated code for Xexun2ProtocolDecoder --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 11 +++++++---- .../java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 3f37d7cac..402095391 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -178,22 +178,25 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(convertCoordinate(buf.readDouble())); } if (BitUtil.check(positionMask, 7)) { - if (buf.readUnsignedShort() > 0) { + int dataLength = buf.readUnsignedShort(); + if (dataLength > 0) { if (buf.readByte() != 'G') { - buf.skipBytes(buf.readUnsignedShort()); + buf.skipBytes(dataLength - 1); } else { int gpsDataLen = buf.readUnsignedShort(); if (gpsDataLen != 27) { - buf.skipBytes(gpsDataLen); + buf.skipBytes(dataLength - 3); } else { + position.setFixTime(position.getDeviceTime()); position.setLongitude(convertCoordinate(buf.readDouble())); position.setLatitude(convertCoordinate(buf.readDouble())); position.setValid(buf.readUnsignedByte() > 0); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - buf.readUnsignedByte(1); // satellite signal to noise ratio + buf.readUnsignedByte(); // satellite signal to noise ratio position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort() * 0.1); position.setAltitude(buf.readFloat()); + buf.skipBytes(dataLength - 30); } } } diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java index 840c38b52..215b90c66 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -25,6 +25,9 @@ public class Xexun2ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "FAAF00140CF18626490454584530002BF2DD0200130013D360EFD7F514006402010D46322C4A450BA026D460EFD7FA14006402010D46322C4A450BA026FAAF")); + verifyPositions(decoder, binary( + "FAAF0014000C8622050512345670002DF3A001002A0062D9047400005E0280001E47001B400D4BA732DF505E40B4153AAF78FEF00109000000000042B36666FAAF")); + } } -- cgit v1.2.3 From 14dafcb4191ec25fa22494956cd509708a9e1b5c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 23 Jul 2022 07:57:02 -0700 Subject: Improve Xexun2 decoder --- .../traccar/protocol/Xexun2ProtocolDecoder.java | 31 +++++++++------------- .../protocol/Xexun2ProtocolDecoderTest.java | 3 ++- 2 files changed, 15 insertions(+), 19 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 402095391..28e7fbda3 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -180,25 +180,20 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(positionMask, 7)) { int dataLength = buf.readUnsignedShort(); if (dataLength > 0) { - if (buf.readByte() != 'G') { - buf.skipBytes(dataLength - 1); - } else { - int gpsDataLen = buf.readUnsignedShort(); - if (gpsDataLen != 27) { - buf.skipBytes(dataLength - 3); - } else { - position.setFixTime(position.getDeviceTime()); - position.setLongitude(convertCoordinate(buf.readDouble())); - position.setLatitude(convertCoordinate(buf.readDouble())); - position.setValid(buf.readUnsignedByte() > 0); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - buf.readUnsignedByte(); // satellite signal to noise ratio - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.setCourse(buf.readUnsignedShort() * 0.1); - position.setAltitude(buf.readFloat()); - buf.skipBytes(dataLength - 30); - } + int dataType = buf.readUnsignedByte(); + int dataEndIndex = buf.readerIndex() + buf.readUnsignedShort(); + if (dataType == 'G') { + position.setFixTime(position.getDeviceTime()); + position.setLongitude(convertCoordinate(buf.readDouble())); + position.setLatitude(convertCoordinate(buf.readDouble())); + position.setValid(buf.readUnsignedByte() > 0); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + buf.readUnsignedByte(); // satellite signal-to-noise ratio + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort() * 0.1); + position.setAltitude(buf.readFloat()); } + buf.readerIndex(dataEndIndex); } } } diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java index 215b90c66..48ba1a691 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -26,7 +26,8 @@ public class Xexun2ProtocolDecoderTest extends ProtocolTest { "FAAF00140CF18626490454584530002BF2DD0200130013D360EFD7F514006402010D46322C4A450BA026D460EFD7FA14006402010D46322C4A450BA026FAAF")); verifyPositions(decoder, binary( - "FAAF0014000C8622050512345670002DF3A001002A0062D9047400005E0280001E47001B400D4BA732DF505E40B4153AAF78FEF00109000000000042B36666FAAF")); + "FAAF0014000C8622050512345670002DF3A001002A0062D9047400005E0280001E47001B400D4BA732DF505E40B4153AAF78FEF00109000000000042B36666FAAF"), + position("2022-07-21 07:47:00.000", true, 51.68715, 0.06103)); } -- cgit v1.2.3 From 4a24779dd6e72247dde96127791ab1f5055b1b53 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 23 Jul 2022 11:52:34 -0700 Subject: Improve iStartek decoding --- .../traccar/protocol/StartekProtocolDecoder.java | 38 +++++++++++++--------- .../protocol/StartekProtocolDecoderTest.java | 6 +++- 2 files changed, 27 insertions(+), 17 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 53c02f28c..b2fcd5452 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -42,6 +42,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("d+,") // length .number("(d+),") // imei .expression("(.+)") // content + .number("xx") // checksum .compile(); private static final Pattern PATTERN_POSITION = new PatternBuilder() @@ -73,22 +74,26 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .groupBegin() .text(",") .number("d,") // extended - .expression("([^,]+)?,") // fuel + .expression("([^,]+)?") // fuel + .groupBegin() + .text(",") .expression("([^,]+)?") // temperature .groupBegin() .text(",") - .number("(d+)|") // rpm - .number("(d+)|") // engine load - .number("d+|") // maf flow - .number("d+|") // intake pressure - .number("d+|") // intake temperature - .number("(d+)|") // throttle - .number("(d+)|") // coolant temperature - .number("(d+)|") // instant fuel - .number("(d+)") // fuel level + .groupBegin() + .number("(d+)?|") // rpm + .number("(d+)?|") // engine load + .number("d*|") // maf flow + .number("d*|") // intake pressure + .number("d*|") // intake temperature + .number("(d+)?|") // throttle + .number("(d+)?|") // coolant temperature + .number("(d+)?|") // instant fuel + .number("(d+)[%L]").optional() // fuel level + .groupEnd("?") + .groupEnd("?") .groupEnd("?") .groupEnd("?") - .any() .compile(); private String decodeAlarm(int value) { @@ -122,9 +127,6 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } String content = parser.next(); - if (content.charAt(content.length() - 2 - 1) != '|') { - content = content.substring(0, content.length() - 2); - } if (content.length() < 100) { Position position = new Position(getProtocolName()); @@ -223,8 +225,12 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); position.set(Position.KEY_THROTTLE, parser.nextInt()); - position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextInt() * 0.1); + if (parser.hasNext()) { + position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); + } + if (parser.hasNext()) { + position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextInt() * 0.1); + } position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); } diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index e8eecae96..072c19942 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,9 +11,13 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = inject(new StartekProtocolDecoder(null)); + verifyAttribute(decoder, text( + "&&x164,869926040743375,000,0,,220705205955,A,33.326001,44.445318,10,1.2,0,57,8,925,418|40|038C|000083CD,31,00000015,00,00,0016|016A|0000|0000,1,,,686|33||44|99|14|124|11|8D"), + Position.KEY_FUEL_CONSUMPTION, 1.1); + verifyAttribute(decoder, text( "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52"), - Position.KEY_FUEL_LEVEL, 52); + Position.KEY_FUEL_LEVEL, null); verifyPosition(decoder, text( "&&o142,860262050066062,000,27,,211111070826,V,28.653435,-106.077455,0,0.0,0,151,1412,918,0|0|4708|01402D19,6,0000001A,02,00,04C0|016C|0000|0000,1,,,BB")); -- cgit v1.2.3 From 929240716f09627de9823d411a11fc0cdf6eb49b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 09:09:17 -0700 Subject: Fix group permissions --- .../java/org/traccar/storage/DatabaseStorage.java | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index eec72b510..8ca464147 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -355,41 +355,45 @@ public class DatabaseStorage extends Storage { result.append("SELECT DISTINCT "); if (!expandDevices) { - result.append(groupStorageName).append('.'); + if (outputKey.equals("groupId")) { + result.append("all_groups."); + } else { + result.append(groupStorageName).append('.'); + } } result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); result.append(" INNER JOIN ("); - result.append("SELECT id as parentid, id as groupid FROM "); + result.append("SELECT id as parentId, id as groupId FROM "); result.append(getStorageName(Group.class)); result.append(" UNION "); - result.append("SELECT groupid as parentid, id as groupid FROM "); + result.append("SELECT groupId as parentId, id as groupId FROM "); result.append(getStorageName(Group.class)); - result.append(" WHERE groupid IS NOT NULL"); + result.append(" WHERE groupId IS NOT NULL"); result.append(" UNION "); - result.append("SELECT g2.groupid as parentid, g1.id as groupid FROM "); + result.append("SELECT g2.groupId as parentId, g1.id as groupId FROM "); result.append(getStorageName(Group.class)); result.append(" AS g2"); result.append(" INNER JOIN "); result.append(getStorageName(Group.class)); - result.append(" AS g1 ON g2.id = g1.groupid"); - result.append(" WHERE g2.groupid IS NOT NULL"); + result.append(" AS g1 ON g2.id = g1.groupId"); + result.append(" WHERE g2.groupId IS NOT NULL"); result.append(") AS all_groups ON "); result.append(groupStorageName); - result.append(".groupid = all_groups.parentid"); + result.append(".groupId = all_groups.parentId"); if (expandDevices) { result.append(" INNER JOIN ("); - result.append("SELECT groupid as parentid, id as deviceid FROM "); + result.append("SELECT groupId as parentId, id as deviceId FROM "); result.append(getStorageName(Device.class)); - result.append(" WHERE groupid IS NOT NULL"); - result.append(") AS devices ON all_groups.groupid = devices.parentid"); + result.append(" WHERE groupId IS NOT NULL"); + result.append(") AS devices ON all_groups.groupId = devices.parentId"); } result.append(" WHERE "); - result.append(conditionKey); // TODO handle search for device / group + result.append(conditionKey); result.append(" = :"); result.append(conditionKey); -- cgit v1.2.3 From eb39a38711c924ae0ecc7ad29ad69e74a95d92d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 14:07:51 -0700 Subject: Avoid copying array --- src/main/java/org/traccar/model/Calendar.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index 102c0be52..c1f98a957 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 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"); @@ -49,13 +49,13 @@ public class Calendar extends ExtendedModel { private byte[] data; public byte[] getData() { - return data.clone(); + return data; } public void setData(byte[] data) throws IOException, ParserException { CalendarBuilder builder = new CalendarBuilder(); calendar = builder.build(new ByteArrayInputStream(data)); - this.data = data.clone(); + this.data = data; } private net.fortuna.ical4j.model.Calendar calendar; -- cgit v1.2.3 From 2daec980de3183efbefc3e79a914a01dc6de910b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 15:42:23 -0700 Subject: Improve query builder --- src/main/java/org/traccar/storage/QueryBuilder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 910ebf170..a58ebe2b4 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -288,7 +288,8 @@ public final class QueryBuilder { Method[] methods = object.getClass().getMethods(); for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 + && !method.getName().equals("getClass")) { String name = method.getName().substring(3); try { if (method.getReturnType().equals(boolean.class)) { -- cgit v1.2.3 From bcd902eaf972ec4cd2befeec0ee0ab0940b7d711 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 15:47:45 -0700 Subject: Crypto signatures support --- schema/changelog-5.3.xml | 12 +++ .../org/traccar/api/signature/CryptoManager.java | 98 ++++++++++++++++++++++ .../org/traccar/api/signature/KeystoreModel.java | 44 ++++++++++ 3 files changed, 154 insertions(+) create mode 100644 src/main/java/org/traccar/api/signature/CryptoManager.java create mode 100644 src/main/java/org/traccar/api/signature/KeystoreModel.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index 063046ce9..a689bc236 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -20,6 +20,18 @@ + + + + + + + + + + + + diff --git a/src/main/java/org/traccar/api/signature/CryptoManager.java b/src/main/java/org/traccar/api/signature/CryptoManager.java new file mode 100644 index 000000000..ea59dcd70 --- /dev/null +++ b/src/main/java/org/traccar/api/signature/CryptoManager.java @@ -0,0 +1,98 @@ +/* + * 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.api.signature; + +import org.traccar.helper.DataConverter; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public class CryptoManager { + + private final Storage storage; + + private PublicKey publicKey; + private PrivateKey privateKey; + + @Inject + public CryptoManager(Storage storage) { + this.storage = storage; + } + + public String sign(String data) throws GeneralSecurityException, StorageException { + if (privateKey == null) { + initializeKeys(); + } + Signature signature = Signature.getInstance("SHA256withECDSA"); + signature.initSign(privateKey); + signature.update(data.getBytes()); + return data + '.' + DataConverter.printBase64(signature.sign()); + } + + public String verify(String data) throws GeneralSecurityException, StorageException { + if (publicKey == null) { + initializeKeys(); + } + Signature signature = Signature.getInstance("SHA256withECDSA"); + signature.initVerify(publicKey); + + int delimiter = data.lastIndexOf('.'); + String originalData = data.substring(0, delimiter); + + signature.update(originalData.getBytes()); + if (!signature.verify(DataConverter.parseBase64(data.substring(delimiter + 1)))) { + throw new SecurityException("Invalid signature"); + } + return originalData; + } + + private void initializeKeys() throws StorageException, GeneralSecurityException { + KeystoreModel model = storage.getObject(KeystoreModel.class, new Request(new Columns.All())); + if (model != null) { + publicKey = KeyFactory.getInstance("EC") + .generatePublic(new X509EncodedKeySpec(model.getPublicKey())); + privateKey = KeyFactory.getInstance("EC") + .generatePrivate(new PKCS8EncodedKeySpec(model.getPrivateKey())); + } else { + KeyPairGenerator generator = KeyPairGenerator.getInstance("EC"); + generator.initialize(new ECGenParameterSpec("secp256r1"), new SecureRandom()); + KeyPair pair = generator.generateKeyPair(); + + publicKey = pair.getPublic(); + privateKey = pair.getPrivate(); + + model = new KeystoreModel(); + model.setPublicKey(publicKey.getEncoded()); + model.setPrivateKey(privateKey.getEncoded()); + storage.addObject(model, new Request(new Columns.Exclude("id"))); + } + } + +} diff --git a/src/main/java/org/traccar/api/signature/KeystoreModel.java b/src/main/java/org/traccar/api/signature/KeystoreModel.java new file mode 100644 index 000000000..7f3140e81 --- /dev/null +++ b/src/main/java/org/traccar/api/signature/KeystoreModel.java @@ -0,0 +1,44 @@ +/* + * 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.api.signature; + +import org.traccar.model.BaseModel; +import org.traccar.storage.StorageName; + +@StorageName("tc_keystore") +public class KeystoreModel extends BaseModel { + + private byte[] publicKey; + + public byte[] getPublicKey() { + return publicKey; + } + + public void setPublicKey(byte[] publicKey) { + this.publicKey = publicKey; + } + + private byte[] privateKey; + + public byte[] getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(byte[] privateKey) { + this.privateKey = privateKey; + } + +} -- cgit v1.2.3 From 032d02b584553f4374c4bc6ae9f7c8e819595c42 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 06:50:59 +0000 Subject: Xexun2 Encoder - Initial Code --- .../java/org/traccar/protocol/Xexun2Protocol.java | 7 ++ .../traccar/protocol/Xexun2ProtocolEncoder.java | 121 +++++++++++++++++++++ .../protocol/Xexun2ProtocolEncoderTest.java | 29 +++++ 3 files changed, 157 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java create mode 100644 src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 4630a69e0..1d5038a22 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -19,6 +19,7 @@ import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import org.traccar.model.Command; import javax.inject.Inject; @@ -26,11 +27,17 @@ public class Xexun2Protocol extends BaseProtocol { @Inject public Xexun2Protocol(Config config) { + setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_POSITION_PERIODIC, + Command.TYPE_POWER_OFF, + Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); + pipeline.addLast(new Xexun2ProtocolEncoder(Xexun2Protocol.this)); } }); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java new file mode 100644 index 000000000..d85c6734b --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -0,0 +1,121 @@ +/* + * 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. + * 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 org.traccar.BaseProtocolEncoder; +import org.traccar.helper.DataConverter; +import org.traccar.model.Command; +import org.traccar.Protocol; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { + + public Xexun2ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private static ByteBuf encodeFrame(ByteBuf buf) { + buf.clear(); + if (buf.readableBytes() < 5) { + return null; + } + + ByteBuf result = Unpooled.buffer(); + + result.writeBytes(buf.readBytes(2)); + + while (buf.readerIndex() < buf.capacity() - 2) { + int b = buf.readUnsignedByte(); + if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { + buf.readUnsignedByte(); + result.writeByte(0xfb); + result.writeByte(0xbf); + result.writeByte(0x01); + } else if (b == 0xfb && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { + buf.readUnsignedByte(); + result.writeByte(0xfb); + result.writeByte(0xbf); + result.writeByte(0x02); + } else { + result.writeByte(b); + } + } + result.writeBytes(buf.readBytes(2)); + + return result; + } + + private static int checksum(byte[] data) + { + int sum = 0; + int len = data.length; + for (int j = 0; len > 1; len--) { + sum += data[j++] & 0xff; + if ((sum & 0x80000000) > 0) { + sum = (sum & 0xffff) + (sum >> 16); + } + } + if (len == 1) { + sum += data[data.length - 1] & 0xff; + } + while ((sum >> 16) > 0) { + sum = (sum & 0xffff) + sum >> 16; + } + sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; + return sum; + } + + + private static ByteBuf encodeContent(String uniqueId, String content) { + ByteBuf buf = Unpooled.buffer(); + + byte[] message = content.getBytes(); + + buf.writeShort(0xFAAF); + buf.writeShort(0x0007); + buf.writeShort(0x0001); + buf.writeBytes(DataConverter.parseHex(uniqueId + "0"),0,8); + buf.writeShort(message.length); + buf.writeShort(checksum(message)); + buf.writeBytes(message); + buf.writeShort(0xFAAF); + + return encodeFrame(buf); + } + + @Override + protected Object encodeCommand(Command command) { + String uniqueId = getUniqueId(command.getDeviceId()); + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_PERIODIC: + return encodeContent(uniqueId, String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + case Command.TYPE_POWER_OFF: + return encodeContent(uniqueId, "of=1"); + case Command.TYPE_REBOOT_DEVICE: + return encodeContent(uniqueId, "reset"); + default: + return null; + } + } + +} diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java new file mode 100644 index 000000000..6d3b3e065 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java @@ -0,0 +1,29 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class Xexun2ProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + var encoder = inject(new Xexun2ProtocolEncoder(null)); + + Command command; + + command = new Command(); + command.setDeviceId(604080829351806311L); + command.setType(Command.TYPE_POWER_OFF); + verifyCommand(encoder, command, binary("FAAF0007000186220505123456700004FEBC6F663D31FAAF")); + + command = new Command(); + command.setDeviceId(604080829351806311L); + command.setType(Command.TYPE_POSITION_PERIODIC); + command.set(Command.KEY_FREQUENCY, 150); + verifyCommand(encoder, command, binary("FAAF0007000186220505123456700015F90E747261636B696E675F73656E643D3135302C313530FAAF")); + + } + +} -- cgit v1.2.3 From 8b63ce5c51fca9462e0e561b8ce07ae49afce6f8 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 13:34:02 +0000 Subject: Update Xexun2 Encoder --- src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 6 +++--- src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index d85c6734b..287364cf2 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -32,8 +32,8 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { } private static ByteBuf encodeFrame(ByteBuf buf) { - buf.clear(); - if (buf.readableBytes() < 5) { + int bufLength = buf.readableBytes(); + if (bufLength < 5) { return null; } @@ -41,7 +41,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { result.writeBytes(buf.readBytes(2)); - while (buf.readerIndex() < buf.capacity() - 2) { + while (buf.readerIndex() < bufLength - 2) { int b = buf.readUnsignedByte(); if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { buf.readUnsignedByte(); diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java index 6d3b3e065..483bc85fa 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java @@ -14,15 +14,15 @@ public class Xexun2ProtocolEncoderTest extends ProtocolTest { Command command; command = new Command(); - command.setDeviceId(604080829351806311L); + command.setDeviceId(1); command.setType(Command.TYPE_POWER_OFF); - verifyCommand(encoder, command, binary("FAAF0007000186220505123456700004FEBC6F663D31FAAF")); + verifyCommand(encoder, command, binary("FAAF0007000112345678901234500004FEBC6F663D31FAAF")); command = new Command(); - command.setDeviceId(604080829351806311L); + command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); command.set(Command.KEY_FREQUENCY, 150); - verifyCommand(encoder, command, binary("FAAF0007000186220505123456700015F90E747261636B696E675F73656E643D3135302C313530FAAF")); + verifyCommand(encoder, command, binary("FAAF0007000112345678901234500015F90E747261636B696E675F73656E643D3135302C313530FAAF")); } -- cgit v1.2.3 From 1f0965d02081d0257a969927ba58de5b39e051bd Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 13:52:06 +0000 Subject: Update Xexun2 Decoder - do not ACK a command ACK --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 28e7fbda3..bdeb0fa78 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,6 +42,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } public static final int MSG_POSITION = 0x14; + public static final int MSG_COMMAND = 0x07; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { @@ -99,12 +100,12 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } - sendResponse(channel, type, index, imei); - buf.readUnsignedShort(); // attributes buf.readUnsignedShort(); // checksum if (type == MSG_POSITION) { + sendResponse(channel, type, index, imei); + List lengths = new ArrayList<>(); List positions = new ArrayList<>(); -- cgit v1.2.3 From e91402cddad8763658572eb8e383fa8a16d69190 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 19:49:37 +0000 Subject: Update Xexun2 Encoder --- .../traccar/protocol/Xexun2ProtocolDecoder.java | 6 ++++-- .../traccar/protocol/Xexun2ProtocolEncoder.java | 24 +++++++++++----------- 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index bdeb0fa78..3c81ec27f 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -100,12 +100,14 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } + if (type != MSG_COMMAND) { + sendResponse(channel, type, index, imei); + } + buf.readUnsignedShort(); // attributes buf.readUnsignedShort(); // checksum if (type == MSG_POSITION) { - sendResponse(channel, type, index, imei); - List lengths = new ArrayList<>(); List positions = new ArrayList<>(); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index 287364cf2..c31d6e747 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,15 +22,15 @@ import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { public Xexun2ProtocolEncoder(Protocol protocol) { super(protocol); } + public static final int FLAG = 0xfaaf; + public static final int MSG_COMMAND = 0x07; + private static ByteBuf encodeFrame(ByteBuf buf) { int bufLength = buf.readableBytes(); if (bufLength < 5) { @@ -62,8 +62,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int checksum(byte[] data) - { + private static int checksum(byte[] data) { int sum = 0; int len = data.length; for (int j = 0; len > 1; len--) { @@ -88,14 +87,14 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { byte[] message = content.getBytes(); - buf.writeShort(0xFAAF); - buf.writeShort(0x0007); - buf.writeShort(0x0001); - buf.writeBytes(DataConverter.parseHex(uniqueId + "0"),0,8); + buf.writeShort(FLAG); + buf.writeShort(MSG_COMMAND); + buf.writeShort(1); // index + buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.length); buf.writeShort(checksum(message)); buf.writeBytes(message); - buf.writeShort(0xFAAF); + buf.writeShort(FLAG); return encodeFrame(buf); } @@ -108,7 +107,8 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { case Command.TYPE_CUSTOM: return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); case Command.TYPE_POSITION_PERIODIC: - return encodeContent(uniqueId, String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + return encodeContent(uniqueId, + String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); case Command.TYPE_POWER_OFF: return encodeContent(uniqueId, "of=1"); case Command.TYPE_REBOOT_DEVICE: -- cgit v1.2.3 From f5033ce11b823a4fce080211368b8c6473d81e7b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 16:59:58 -0700 Subject: Rename mail manager --- .../java/org/traccar/database/MailManager.java | 161 -------------------- .../java/org/traccar/mail/SmtpMailManager.java | 162 +++++++++++++++++++++ 2 files changed, 162 insertions(+), 161 deletions(-) delete mode 100644 src/main/java/org/traccar/database/MailManager.java create mode 100644 src/main/java/org/traccar/mail/SmtpMailManager.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java deleted file mode 100644 index ec1681dcb..000000000 --- a/src/main/java/org/traccar/database/MailManager.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2017 - 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.database; - -import org.traccar.config.Config; -import org.traccar.config.ConfigKey; -import org.traccar.config.Keys; -import org.traccar.model.User; -import org.traccar.notification.PropertiesProvider; - -import javax.inject.Inject; -import javax.mail.BodyPart; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import java.io.UnsupportedEncodingException; -import java.util.Date; -import java.util.Properties; - -public final class MailManager { - - private static final String CONTENT_TYPE = "text/html; charset=utf-8"; - - private final Config config; - private final StatisticsManager statisticsManager; - - @Inject - public MailManager(Config config, StatisticsManager statisticsManager) { - this.config = config; - this.statisticsManager = statisticsManager; - } - - private static void copyBooleanProperty( - Properties properties, PropertiesProvider provider, ConfigKey key) { - Boolean value = provider.getBoolean(key); - if (value != null) { - properties.put(key.getKey(), String.valueOf(value)); - } - } - - private static void copyStringProperty( - Properties properties, PropertiesProvider provider, ConfigKey key) { - String value = provider.getString(key); - if (value != null) { - properties.put(key.getKey(), value); - } - } - - private static Properties getProperties(PropertiesProvider provider) { - String host = provider.getString(Keys.MAIL_SMTP_HOST); - if (host != null) { - Properties properties = new Properties(); - - properties.put(Keys.MAIL_TRANSPORT_PROTOCOL.getKey(), provider.getString(Keys.MAIL_TRANSPORT_PROTOCOL)); - properties.put(Keys.MAIL_SMTP_HOST.getKey(), host); - properties.put(Keys.MAIL_SMTP_PORT.getKey(), String.valueOf(provider.getInteger(Keys.MAIL_SMTP_PORT))); - - copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_ENABLE); - copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_REQUIRED); - copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_SSL_ENABLE); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_TRUST); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_PROTOCOLS); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_USERNAME); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_PASSWORD); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM_NAME); - - return properties; - } - return null; - } - - public boolean getEmailEnabled() { - return config.hasKey(Keys.MAIL_SMTP_HOST); - } - - public void sendMessage( - User user, String subject, String body) throws MessagingException { - sendMessage(user, subject, body, null); - } - - public void sendMessage( - User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { - - Properties properties = null; - if (!config.getBoolean(Keys.MAIL_SMTP_IGNORE_USER_CONFIG)) { - properties = getProperties(new PropertiesProvider(user)); - } - if (properties == null) { - properties = getProperties(new PropertiesProvider(config)); - } - if (properties == null) { - throw new MessagingException("No SMTP configuration found"); - } - - Session session = Session.getInstance(properties); - - MimeMessage message = new MimeMessage(session); - - String from = properties.getProperty(Keys.MAIL_SMTP_FROM.getKey()); - if (from != null) { - String fromName = properties.getProperty(Keys.MAIL_SMTP_FROM_NAME.getKey()); - if (fromName != null) { - try { - message.setFrom(new InternetAddress(from, fromName)); - } catch (UnsupportedEncodingException e) { - throw new MessagingException("Email address issue"); - } - } else { - message.setFrom(new InternetAddress(from)); - } - } - - message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); - message.setSubject(subject); - message.setSentDate(new Date()); - - if (attachment != null) { - Multipart multipart = new MimeMultipart(); - - BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setContent(body, CONTENT_TYPE); - multipart.addBodyPart(messageBodyPart); - multipart.addBodyPart(attachment); - - message.setContent(multipart); - } else { - message.setContent(body, CONTENT_TYPE); - } - - try (Transport transport = session.getTransport()) { - statisticsManager.registerMail(); - transport.connect( - properties.getProperty(Keys.MAIL_SMTP_HOST.getKey()), - properties.getProperty(Keys.MAIL_SMTP_USERNAME.getKey()), - properties.getProperty(Keys.MAIL_SMTP_PASSWORD.getKey())); - transport.sendMessage(message, message.getAllRecipients()); - } - } - -} diff --git a/src/main/java/org/traccar/mail/SmtpMailManager.java b/src/main/java/org/traccar/mail/SmtpMailManager.java new file mode 100644 index 000000000..7763c86cc --- /dev/null +++ b/src/main/java/org/traccar/mail/SmtpMailManager.java @@ -0,0 +1,162 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 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.mail; + +import org.traccar.config.Config; +import org.traccar.config.ConfigKey; +import org.traccar.config.Keys; +import org.traccar.database.StatisticsManager; +import org.traccar.model.User; +import org.traccar.notification.PropertiesProvider; + +import javax.inject.Inject; +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.util.Properties; + +public final class SmtpMailManager implements MailManager { + + private static final String CONTENT_TYPE = "text/html; charset=utf-8"; + + private final Config config; + private final StatisticsManager statisticsManager; + + @Inject + public SmtpMailManager(Config config, StatisticsManager statisticsManager) { + this.config = config; + this.statisticsManager = statisticsManager; + } + + private static void copyBooleanProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + Boolean value = provider.getBoolean(key); + if (value != null) { + properties.put(key.getKey(), String.valueOf(value)); + } + } + + private static void copyStringProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + String value = provider.getString(key); + if (value != null) { + properties.put(key.getKey(), value); + } + } + + private static Properties getProperties(PropertiesProvider provider) { + String host = provider.getString(Keys.MAIL_SMTP_HOST); + if (host != null) { + Properties properties = new Properties(); + + properties.put(Keys.MAIL_TRANSPORT_PROTOCOL.getKey(), provider.getString(Keys.MAIL_TRANSPORT_PROTOCOL)); + properties.put(Keys.MAIL_SMTP_HOST.getKey(), host); + properties.put(Keys.MAIL_SMTP_PORT.getKey(), String.valueOf(provider.getInteger(Keys.MAIL_SMTP_PORT))); + + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_ENABLE); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_REQUIRED); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_SSL_ENABLE); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_TRUST); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_PROTOCOLS); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_USERNAME); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_PASSWORD); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM_NAME); + + return properties; + } + return null; + } + + public boolean getEmailEnabled() { + return config.hasKey(Keys.MAIL_SMTP_HOST); + } + + public void sendMessage( + User user, String subject, String body) throws MessagingException { + sendMessage(user, subject, body, null); + } + + public void sendMessage( + User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + + Properties properties = null; + if (!config.getBoolean(Keys.MAIL_SMTP_IGNORE_USER_CONFIG)) { + properties = getProperties(new PropertiesProvider(user)); + } + if (properties == null) { + properties = getProperties(new PropertiesProvider(config)); + } + if (properties == null) { + throw new MessagingException("No SMTP configuration found"); + } + + Session session = Session.getInstance(properties); + + MimeMessage message = new MimeMessage(session); + + String from = properties.getProperty(Keys.MAIL_SMTP_FROM.getKey()); + if (from != null) { + String fromName = properties.getProperty(Keys.MAIL_SMTP_FROM_NAME.getKey()); + if (fromName != null) { + try { + message.setFrom(new InternetAddress(from, fromName)); + } catch (UnsupportedEncodingException e) { + throw new MessagingException("Email address issue"); + } + } else { + message.setFrom(new InternetAddress(from)); + } + } + + message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); + message.setSubject(subject); + message.setSentDate(new Date()); + + if (attachment != null) { + Multipart multipart = new MimeMultipart(); + + BodyPart messageBodyPart = new MimeBodyPart(); + messageBodyPart.setContent(body, CONTENT_TYPE); + multipart.addBodyPart(messageBodyPart); + multipart.addBodyPart(attachment); + + message.setContent(multipart); + } else { + message.setContent(body, CONTENT_TYPE); + } + + try (Transport transport = session.getTransport()) { + statisticsManager.registerMail(); + transport.connect( + properties.getProperty(Keys.MAIL_SMTP_HOST.getKey()), + properties.getProperty(Keys.MAIL_SMTP_USERNAME.getKey()), + properties.getProperty(Keys.MAIL_SMTP_PASSWORD.getKey())); + transport.sendMessage(message, message.getAllRecipients()); + } + } + +} -- cgit v1.2.3 From 8f129e2a70abbea66f33213c84b7e63f9e96035a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 17:12:51 -0700 Subject: Testing mail manager --- debug.xml | 2 + src/main/java/org/traccar/MainModule.java | 12 ++++++ .../org/traccar/api/resource/PasswordResource.java | 2 +- .../org/traccar/api/resource/ReportResource.java | 2 +- .../org/traccar/api/resource/ServerResource.java | 2 +- src/main/java/org/traccar/config/Keys.java | 7 ++++ src/main/java/org/traccar/mail/LogMailManager.java | 44 ++++++++++++++++++++++ src/main/java/org/traccar/mail/MailManager.java | 31 +++++++++++++++ .../java/org/traccar/mail/SmtpMailManager.java | 2 - .../org/traccar/notificators/NotificatorMail.java | 2 +- 10 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/traccar/mail/LogMailManager.java create mode 100644 src/main/java/org/traccar/mail/MailManager.java (limited to 'src/main/java/org') diff --git a/debug.xml b/debug.xml index a597d83c5..b38b4f9ac 100644 --- a/debug.xml +++ b/debug.xml @@ -16,6 +16,8 @@ true true + true + org.h2.Driver jdbc:h2:./target/database sa diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b9543af25..b8ff21472 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -63,6 +63,9 @@ import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; import org.traccar.helper.SanitizerModule; +import org.traccar.mail.LogMailManager; +import org.traccar.mail.MailManager; +import org.traccar.mail.SmtpMailManager; import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; @@ -128,6 +131,15 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static MailManager provideMailManager(Config config, StatisticsManager statisticsManager) { + if (config.getBoolean(Keys.MAIL_DEBUG)) { + return new LogMailManager(); + } else { + return new SmtpMailManager(config, statisticsManager); + } + } + @Singleton @Provides public static LdapProvider provideLdapProvider(Config config) { diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 643471797..88906e7e6 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -16,7 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.model.User; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 6176013c1..70177dd4d 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -19,7 +19,7 @@ package org.traccar.api.resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.BaseResource; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 4fc76a0d7..e35cd7d95 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -16,7 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.helper.LogAction; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 2190f82f7..e97e104a1 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -800,6 +800,13 @@ public final class Keys { List.of(KeyType.CONFIG), "templates"); + /** + * Log emails instead of sending them via SMTP. Intended for testing purposes only. + */ + public static final ConfigKey MAIL_DEBUG = new BooleanConfigKey( + "mail.debug", + List.of(KeyType.CONFIG)); + /** * Force SMTP settings from the config file and ignore user attributes. */ diff --git a/src/main/java/org/traccar/mail/LogMailManager.java b/src/main/java/org/traccar/mail/LogMailManager.java new file mode 100644 index 000000000..b6b912d6c --- /dev/null +++ b/src/main/java/org/traccar/mail/LogMailManager.java @@ -0,0 +1,44 @@ +/* + * 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.mail; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.model.User; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; + +public class LogMailManager implements MailManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(LogMailManager.class); + + @Override + public boolean getEmailEnabled() { + return true; + } + + @Override + public void sendMessage(User user, String subject, String body) throws MessagingException { + sendMessage(user, subject, body, null); + } + + @Override + public void sendMessage(User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + LOGGER.info("\nTo: " + user.getEmail() + "\nSubject: " + subject + "\nBody:\n" + body); + } + +} diff --git a/src/main/java/org/traccar/mail/MailManager.java b/src/main/java/org/traccar/mail/MailManager.java new file mode 100644 index 000000000..69efbed32 --- /dev/null +++ b/src/main/java/org/traccar/mail/MailManager.java @@ -0,0 +1,31 @@ +/* + * 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.mail; + +import org.traccar.model.User; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; + +public interface MailManager { + + boolean getEmailEnabled(); + + void sendMessage(User user, String subject, String body) throws MessagingException; + + void sendMessage(User user, String subject, String body, MimeBodyPart attachment) throws MessagingException; + +} diff --git a/src/main/java/org/traccar/mail/SmtpMailManager.java b/src/main/java/org/traccar/mail/SmtpMailManager.java index 7763c86cc..4a0b7048f 100644 --- a/src/main/java/org/traccar/mail/SmtpMailManager.java +++ b/src/main/java/org/traccar/mail/SmtpMailManager.java @@ -23,7 +23,6 @@ import org.traccar.database.StatisticsManager; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; -import javax.inject.Inject; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; @@ -45,7 +44,6 @@ public final class SmtpMailManager implements MailManager { private final Config config; private final StatisticsManager statisticsManager; - @Inject public SmtpMailManager(Config config, StatisticsManager statisticsManager) { this.config = config; this.statisticsManager = statisticsManager; diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 647832166..75571cfc4 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -16,7 +16,7 @@ */ package org.traccar.notificators; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -- cgit v1.2.3 From 535eb8d11fccfa7ba4bfcbe9e3d8a0bc9be8f247 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 17:17:24 -0700 Subject: Fix password reset --- src/main/java/org/traccar/api/resource/PasswordResource.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 88906e7e6..91c2d8ecf 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -58,7 +58,8 @@ public class PasswordResource extends BaseResource { if (user != null) { String token = UUID.randomUUID().toString().replaceAll("-", ""); user.set(PASSWORD_RESET_TOKEN, token); - storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + storage.updateObject(user, new Request( + new Columns.Include("attributes"), new Condition.Equals("id", "id"))); var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); velocityContext.put("token", token); @@ -79,7 +80,8 @@ public class PasswordResource extends BaseResource { if (user != null) { user.getAttributes().remove(PASSWORD_RESET_TOKEN); user.setPassword(password); - storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + storage.updateObject(user, new Request( + new Columns.Include("attributes", "hashedPassword", "salt"), new Condition.Equals("id", "id"))); return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); -- cgit v1.2.3 From c5f793815a6429d77c429f49c876f52062051f03 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 17:29:14 -0700 Subject: Handle connectionless protocols --- src/main/java/org/traccar/MainEventHandler.java | 7 +++---- src/main/java/org/traccar/session/ConnectionManager.java | 6 ++++-- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 981888577..52eb43faf 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -159,10 +159,9 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.info("[{}] disconnected", NetworkUtil.session(ctx.channel())); closeChannel(ctx.channel()); - if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null - && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - connectionManager.deviceDisconnected(ctx.channel()); - } + boolean supportsOffline = BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null + && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName()); + connectionManager.deviceDisconnected(ctx.channel(), supportsOffline); } @Override diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 2d183ee22..262a302af 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -189,12 +189,14 @@ public class ConnectionManager implements BroadcastInterface { } } - public void deviceDisconnected(Channel channel) { + public void deviceDisconnected(Channel channel, boolean supportsOffline) { Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); Map endpointSessions = sessionsByEndpoint.remove(endpoint); if (endpointSessions != null) { for (DeviceSession deviceSession : endpointSessions.values()) { - updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); + if (supportsOffline) { + updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); + } sessionsByDeviceId.remove(deviceSession.getDeviceId()); cacheManager.removeDevice(deviceSession.getDeviceId()); } -- cgit v1.2.3 From de2219565e4a61aa0d64b03650ec36ef6d17de93 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Wed, 27 Jul 2022 15:47:18 +0100 Subject: Update Xexun2 Encoder --- .../java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 9 +++------ .../java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 15 ++++++++------- 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 3c81ec27f..8deb2328b 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,13 +42,11 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } public static final int MSG_POSITION = 0x14; - public static final int MSG_COMMAND = 0x07; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { ByteBuf response = Unpooled.buffer(); - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(Xexun2ProtocolEncoder.FLAG); response.writeShort(type); response.writeShort(index); @@ -57,8 +55,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0xfffe); // checksum response.writeByte(1); // response - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(Xexun2ProtocolEncoder.FLAG); channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } @@ -100,7 +97,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } - if (type != MSG_COMMAND) { + if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { sendResponse(channel, type, index, imei); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index c31d6e747..f876853bf 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -62,17 +62,17 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int checksum(byte[] data) { + private static int udpchecksum(ByteBuf data) { int sum = 0; - int len = data.length; + int len = data.capacity(); for (int j = 0; len > 1; len--) { - sum += data[j++] & 0xff; + sum += data.readByte() & 0xff; if ((sum & 0x80000000) > 0) { sum = (sum & 0xffff) + (sum >> 16); } } if (len == 1) { - sum += data[data.length - 1] & 0xff; + sum += data.readByte() & 0xff; } while ((sum >> 16) > 0) { sum = (sum & 0xffff) + sum >> 16; @@ -85,14 +85,15 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); - byte[] message = content.getBytes(); + ByteBuf message = Unpooled.copiedBuffer(content.getBytes()); buf.writeShort(FLAG); buf.writeShort(MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); - buf.writeShort(message.length); - buf.writeShort(checksum(message)); + buf.writeShort(message.capacity()); + buf.writeShort(udpchecksum(message)); + message.resetReaderIndex(); buf.writeBytes(message); buf.writeShort(FLAG); -- cgit v1.2.3 From 42e88c2bf95962f1274a8bbb6e8fc09af95f627f Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Thu, 28 Jul 2022 22:37:15 +0100 Subject: Added udp() to Checksum helper and Updated Xexun2 procotol --- src/main/java/org/traccar/helper/Checksum.java | 19 +++++++++++++++++ .../traccar/protocol/Xexun2ProtocolDecoder.java | 11 +++++++--- .../traccar/protocol/Xexun2ProtocolEncoder.java | 24 ++-------------------- 3 files changed, 29 insertions(+), 25 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/Checksum.java b/src/main/java/org/traccar/helper/Checksum.java index 8c3d0063a..e660790ef 100644 --- a/src/main/java/org/traccar/helper/Checksum.java +++ b/src/main/java/org/traccar/helper/Checksum.java @@ -200,4 +200,23 @@ public final class Checksum { return (10 - (checksum % 10)) % 10; } + public static int udp(ByteBuffer data) { + int sum = 0; + int len = data.capacity(); + for (int j = 0; len > 1; len--) { + sum += data.get() & 0xff; + if ((sum & 0x80000000) > 0) { + sum = (sum & 0xffff) + (sum >> 16); + } + } + if (len == 1) { + sum += data.get() & 0xff; + } + while ((sum >> 16) > 0) { + sum = (sum & 0xffff) + sum >> 16; + } + sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; + return sum; + } + } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 8deb2328b..f0158e6ce 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -24,6 +24,7 @@ import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -97,13 +98,17 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } + int payloadSize = buf.readUnsignedShort() & 0x03ff; + int checksum = buf.readUnsignedShort(); // checksum + + if (checksum != Checksum.udp(buf.nioBuffer(buf.readerIndex(), payloadSize))) { + return null; + } + if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { sendResponse(channel, type, index, imei); } - buf.readUnsignedShort(); // attributes - buf.readUnsignedShort(); // checksum - if (type == MSG_POSITION) { List lengths = new ArrayList<>(); List positions = new ArrayList<>(); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index f876853bf..6e1e1d68d 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; @@ -62,26 +63,6 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int udpchecksum(ByteBuf data) { - int sum = 0; - int len = data.capacity(); - for (int j = 0; len > 1; len--) { - sum += data.readByte() & 0xff; - if ((sum & 0x80000000) > 0) { - sum = (sum & 0xffff) + (sum >> 16); - } - } - if (len == 1) { - sum += data.readByte() & 0xff; - } - while ((sum >> 16) > 0) { - sum = (sum & 0xffff) + sum >> 16; - } - sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; - return sum; - } - - private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); @@ -92,8 +73,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.capacity()); - buf.writeShort(udpchecksum(message)); - message.resetReaderIndex(); + buf.writeShort(Checksum.udp(message.nioBuffer())); buf.writeBytes(message); buf.writeShort(FLAG); -- cgit v1.2.3 From f028f926ad1c59268c591d1f095f0f77e36a814a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:20:01 -0700 Subject: Better missing file handing --- src/main/java/org/traccar/web/WebServer.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 68eee78e7..704a4b3cd 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -64,6 +64,7 @@ import java.io.IOException; import java.io.Writer; import java.net.InetSocketAddress; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.EnumSet; @@ -104,9 +105,9 @@ public class WebServer implements LifecycleObject { @Override protected void handleErrorPage( HttpServletRequest request, Writer writer, int code, String message) throws IOException { - if (code == HttpStatus.NOT_FOUND_404 && request.getPathInfo().startsWith("/modern")) { - writer.write(Files.readString( - Paths.get(config.getString(Keys.WEB_PATH), "modern", "index.html"))); + Path index = Paths.get(config.getString(Keys.WEB_PATH), "index.html"); + if (code == HttpStatus.NOT_FOUND_404 && Files.exists(index)) { + writer.write(Files.readString(index)); } else { writer.write("Error" + code + " - " + HttpStatus.getMessage(code) + ""); -- cgit v1.2.3 From 91584d16eb8585d302d52b76058b7cc5c6b74d4f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 10:13:28 -0700 Subject: Minor Teltonika refactoring --- .../java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 77047fe26..a7c46402f 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -197,13 +197,13 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeOtherParameter(Position position, int id, ByteBuf buf, int length) { + private void decodeUniversalParameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 1: case 2: case 3: case 4: - position.set("di" + id, readValue(buf, length, false)); + position.set(Position.PREFIX_IN + id, readValue(buf, length, false)); break; case 9: position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); @@ -355,7 +355,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { - decodeOtherParameter(position, id, buf, length); + decodeUniversalParameter(position, id, buf, length); } } @@ -508,7 +508,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeOtherParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8, codec); } } -- cgit v1.2.3 From 54bcbdc6ed9aec8fe5bdfa76dfc7698f7504df84 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 11:25:52 -0700 Subject: Rename variable --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 88b7d12c8..8a58ebc5e 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -204,11 +204,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); } - String deviceModel = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); - if (deviceModel == null) { - deviceModel = ""; + String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); + if (model == null) { + model = ""; } - switch (deviceModel.toUpperCase()) { + switch (model.toUpperCase()) { case "MVT340": case "MVT380": position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.0 * 2.0 / 1024.0); -- cgit v1.2.3 From 2d0d2cd39b40a1b62435efaa193bcf4680f109db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 11:26:23 -0700 Subject: Better Teltonika support (fix #3988) --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 254 ++++++++++----------- 1 file changed, 117 insertions(+), 137 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index a7c46402f..2b1196d55 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.model.Device; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -38,11 +39,15 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { private static final int IMAGE_PACKET_MAX = 2048; + private static final Map, BiConsumer>> PARAMETERS = new HashMap<>(); + private final boolean connectionless; private boolean extended; private final Map photos = new HashMap<>(); @@ -184,185 +189,160 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private long readValue(ByteBuf buf, int length, boolean signed) { + private long readValue(ByteBuf buf, int length) { switch (length) { case 1: - return signed ? buf.readByte() : buf.readUnsignedByte(); + return buf.readUnsignedByte(); case 2: - return signed ? buf.readShort() : buf.readUnsignedShort(); + return buf.readUnsignedShort(); case 4: - return signed ? buf.readInt() : buf.readUnsignedInt(); + return buf.readUnsignedInt(); default: return buf.readLong(); } } - private void decodeUniversalParameter(Position position, int id, ByteBuf buf, int length) { - switch (id) { - case 1: - case 2: - case 3: - case 4: - position.set(Position.PREFIX_IN + id, readValue(buf, length, false)); - break; - case 9: - position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); - break; - case 10: - position.set(Position.PREFIX_ADC + 2, readValue(buf, length, false)); - break; - case 16: - position.set(Position.KEY_ODOMETER, readValue(buf, length, false)); - break; - case 17: - position.set("axisX", readValue(buf, length, true)); - break; - case 18: - position.set("axisY", readValue(buf, length, true)); - break; - case 19: - position.set("axisZ", readValue(buf, length, true)); - break; - case 21: - position.set(Position.KEY_RSSI, readValue(buf, length, false)); - break; - case 25: - case 26: - case 27: - case 28: - position.set(Position.PREFIX_TEMP + (id - 24 + 4), readValue(buf, length, true) * 0.1); - break; - case 66: - position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); - break; - case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); - break; - case 72: - case 73: - case 74: - position.set(Position.PREFIX_TEMP + (id - 71), readValue(buf, length, true) * 0.1); - break; - case 78: - long driverUniqueId = readValue(buf, length, false); - if (driverUniqueId != 0) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); - } - break; - case 80: - position.set("workMode", readValue(buf, length, false)); - break; - case 90: - position.set(Position.KEY_DOOR, readValue(buf, length, false)); - break; - case 115: - position.set(Position.KEY_COOLANT_TEMP, readValue(buf, length, true) * 0.1); - break; - case 179: - position.set(Position.PREFIX_OUT + 1, readValue(buf, length, false) == 1); - break; - case 180: - position.set(Position.PREFIX_OUT + 2, readValue(buf, length, false) == 1); - break; - case 181: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); - break; - case 182: - position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); - break; - case 199: - position.set(Position.KEY_ODOMETER_TRIP, readValue(buf, length, false)); - break; - case 236: - if (readValue(buf, length, false) == 1) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - break; - case 239: - position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); - break; - case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); - break; - case 241: - position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); - break; - case 253: - switch ((int) readValue(buf, length, false)) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - break; - } - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); - break; - } + private static void register(int id, Set models, BiConsumer handler) { + PARAMETERS.computeIfAbsent(id, key -> new HashMap<>()).put(models, handler); + } + + static { + var fmbXXX = Set.of( + "FMB001", "FMB010", "FMB002", "FMB020", "FMB003", "FMB110", "FMB120", "FMB122", "FMB125", "FMB130", + "FMB140", "FMU125", "FMB900", "FMB920", "FMB962", "FMB964", "FM3001", "FMB202", "FMB204", "FMB206", + "FMT100", "MTB100", "FMP100", "MSP500"); + + register(1, null, (p, b) -> p.set(Position.PREFIX_IN + 1, b.readUnsignedByte() > 0)); + register(2, null, (p, b) -> p.set(Position.PREFIX_IN + 2, b.readUnsignedByte() > 0)); + register(3, null, (p, b) -> p.set(Position.PREFIX_IN + 3, b.readUnsignedByte() > 0)); + register(4, null, (p, b) -> p.set(Position.PREFIX_IN + 4, b.readUnsignedByte() > 0)); + register(9, fmbXXX, (p, b) -> p.set(Position.PREFIX_ADC + 1, b.readUnsignedShort() * 0.001)); + register(10, fmbXXX, (p, b) -> p.set(Position.PREFIX_ADC + 2, b.readUnsignedShort() * 0.001)); + register(11, fmbXXX, (p, b) -> p.set(Position.KEY_ICCID, String.valueOf(b.readLong()))); + register(12, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_USED, b.readUnsignedInt() * 0.001)); + register(13, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_CONSUMPTION, b.readUnsignedShort() * 0.01)); + register(16, null, (p, b) -> p.set(Position.KEY_ODOMETER, b.readUnsignedInt())); + register(17, null, (p, b) -> p.set("axisX", b.readShort())); + register(18, null, (p, b) -> p.set("axisY", b.readShort())); + register(19, null, (p, b) -> p.set("axisZ", b.readShort())); + register(21, null, (p, b) -> p.set(Position.KEY_RSSI, b.readUnsignedByte())); + register(24, fmbXXX, (p, b) -> p.setSpeed(UnitsConverter.knotsFromKph(b.readUnsignedShort()))); + register(25, null, (p, b) -> p.set("bleTemp1", b.readShort() * 0.01)); + register(26, null, (p, b) -> p.set("bleTemp2", b.readShort() * 0.01)); + register(27, null, (p, b) -> p.set("bleTemp3", b.readShort() * 0.01)); + register(28, null, (p, b) -> p.set("bleTemp4", b.readShort() * 0.01)); + register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); + register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); + register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); + register(72, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 1, b.readShort() * 0.1)); + register(73, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 2, b.readShort() * 0.1)); + register(74, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 3, b.readShort() * 0.1)); + register(75, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 4, b.readShort() * 0.1)); + register(78, null, (p, b) -> { + long driverUniqueId = b.readLong(); + if (driverUniqueId > 0) { + p.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); + } + }); + register(80, null, (p, b) -> p.set("dataMode", b.readUnsignedByte())); + register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); + register(115, fmbXXX, (p, b) -> p.set(Position.KEY_COOLANT_TEMP, b.readShort() * 0.1)); + register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); + register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); + register(181, null, (p, b) -> p.set(Position.KEY_PDOP, b.readUnsignedShort() * 0.1)); + register(182, null, (p, b) -> p.set(Position.KEY_HDOP, b.readUnsignedShort() * 0.1)); + register(199, null, (p, b) -> p.set(Position.KEY_ODOMETER_TRIP, b.readUnsignedInt())); + register(200, fmbXXX, (p, b) -> p.set("sleepMode", b.readUnsignedByte())); + register(205, null, (p, b) -> p.set("cid", b.readUnsignedShort())); + register(206, null, (p, b) -> p.set("lac", b.readUnsignedShort())); + register(236, null, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); + }); + register(239, null, (p, b) -> p.set(Position.KEY_IGNITION, b.readUnsignedByte() > 0)); + register(240, null, (p, b) -> p.set(Position.KEY_MOTION, b.readUnsignedByte() > 0)); + register(241, null, (p, b) -> p.set(Position.KEY_OPERATOR, b.readUnsignedInt())); + register(253, null, (p, b) -> { + switch (b.readUnsignedByte()) { + case 1: + p.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 2: + p.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 3: + p.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + break; + } + }); } private void decodeGh3000Parameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 1: - position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length, false)); + position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length)); break; case 2: - position.set("usbConnected", readValue(buf, length, false) == 1); + position.set("usbConnected", readValue(buf, length) == 1); break; case 5: - position.set("uptime", readValue(buf, length, false)); + position.set("uptime", readValue(buf, length)); break; case 20: - position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_HDOP, readValue(buf, length) * 0.1); break; case 21: - position.set(Position.KEY_VDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_VDOP, readValue(buf, length) * 0.1); break; case 22: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_PDOP, readValue(buf, length) * 0.1); break; case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); + position.set(Position.KEY_BATTERY, readValue(buf, length) * 0.001); break; case 221: - position.set("button", readValue(buf, length, false)); + position.set("button", readValue(buf, length)); break; case 222: - if (readValue(buf, length, false) == 1) { + if (readValue(buf, length) == 1) { position.set(Position.KEY_ALARM, Position.ALARM_SOS); } break; case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + position.set(Position.KEY_MOTION, readValue(buf, length) == 1); break; case 244: - position.set(Position.KEY_ROAMING, readValue(buf, length, false) == 1); + position.set(Position.KEY_ROAMING, readValue(buf, length) == 1); break; default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); + position.set(Position.PREFIX_IO + id, readValue(buf, length)); break; } } - private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec) { + private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec, String model) { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { - decodeUniversalParameter(position, id, buf, length); + boolean decoded = false; + for (var entry : PARAMETERS.getOrDefault(id, new HashMap<>()).entrySet()) { + if (entry.getKey() == null || model != null && entry.getKey().contains(model)) { + entry.getValue().accept(position, buf); + decoded = true; + break; + } + } + if (!decoded) { + position.set(Position.PREFIX_IO + id, readValue(buf, length)); + } } } private void decodeNetwork(Position position) { - long cid = position.getLong(Position.PREFIX_IO + 205); - int lac = position.getInteger(Position.PREFIX_IO + 206); - if (cid != 0 && lac != 0) { + Integer cid = (Integer) position.getAttributes().remove("cid"); + Integer lac = (Integer) position.getAttributes().remove("lac"); + if (cid != null && lac != null) { CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); long operator = position.getInteger(Position.KEY_OPERATOR); if (operator >= 1000) { @@ -387,7 +367,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeLocation(Position position, ByteBuf buf, int codec) { + private void decodeLocation(Position position, ByteBuf buf, int codec, String model) { int globalMask = 0x0f; @@ -484,7 +464,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 1)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec, model); } } @@ -492,7 +472,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 2)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec, model); } } @@ -500,7 +480,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 3)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec, model); } } @@ -508,7 +488,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8, codec, model); } } @@ -578,10 +558,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { int count = buf.readUnsignedByte(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { return null; } + String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); for (int i = 0; i < count; i++) { Position position = new Position(getProtocolName()); @@ -603,7 +583,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } else if (codec == CODEC_12) { decodeSerial(channel, remoteAddress, deviceSession, position, buf); } else { - decodeLocation(position, buf, codec); + decodeLocation(position, buf, codec, model); } if (!position.getOutdated() || !position.getAttributes().isEmpty()) { -- cgit v1.2.3 From 910965c3d08745d68cbf812ed96eef7323dbb893 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 1 Aug 2022 19:06:04 -0700 Subject: Handle GPS103 no GPS (fix #4915) --- src/main/java/org/traccar/helper/Parser.java | 13 +++++++------ .../java/org/traccar/protocol/Gps103ProtocolDecoder.java | 15 ++++++++++----- .../org/traccar/protocol/Gps103ProtocolDecoderTest.java | 6 +++++- 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/Parser.java b/src/main/java/org/traccar/helper/Parser.java index 22e98ded1..aa39e1ad7 100644 --- a/src/main/java/org/traccar/helper/Parser.java +++ b/src/main/java/org/traccar/helper/Parser.java @@ -48,13 +48,14 @@ public class Parser { } public boolean hasNext(int number) { - String value = matcher.group(position); - if (value != null && !value.isEmpty()) { - return true; - } else { - position += number; - return false; + for (int i = position; i < position + number; i++) { + String value = matcher.group(i); + if (value != null && !value.isEmpty()) { + return true; + } } + position += number; + return false; } public String next() { diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index b63bcd0c0..28efa3c30 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -56,9 +56,12 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .expression("([^,]+)?,") // rfid .groupBegin() - .text("L,,,") + .text("L,") + .groupBegin() + .text(",,") .number("(x+),,") // lac .number("(x+),,,") // cid + .groupEnd("?") .or() .text("F,") .groupBegin() @@ -218,13 +221,11 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext(2)) { - - getLastLocation(position, null); - position.setNetwork(new Network(CellTower.fromLacCid( getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); + } - } else { + if (parser.hasNext(20)) { String utcHours = parser.next(); String utcMinutes = parser.next(); @@ -262,6 +263,10 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set("fuel2", parser.nextDouble()); position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + } else { + + getLastLocation(position, null); + } return position; diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java index 425fcd8ae..cf5786d75 100644 --- a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gps103ProtocolDecoder(null)); + verifyAttribute(decoder, text( + "imei:865456055519122,sensor alarm,2208011920,,L,;"), + Position.KEY_ALARM, Position.ALARM_VIBRATION); + verifyPosition(decoder, text( "imei:864035050002451,tracker,201223064947,,F,064947,A,1935.70640,N,09859.94436,W,0.025,;")); @@ -155,7 +159,7 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { "359586015829802")); // No GPS signal - verifyNull(decoder, text( + verifyNotNull(decoder, text( "imei:359586015829802,tracker,000000000,13554900601,L,;")); verifyPosition(decoder, text( -- cgit v1.2.3 From ab6970135850655313e257cf44fb68c67e9f1e80 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 19:16:11 -0700 Subject: New API token system --- schema/changelog-5.3.xml | 2 + .../org/traccar/api/resource/SessionResource.java | 30 ++++++++-- .../org/traccar/api/security/LoginService.java | 13 ++++- .../api/security/SecurityRequestFilter.java | 4 +- .../org/traccar/api/signature/CryptoManager.java | 25 +++++---- .../org/traccar/api/signature/TokenManager.java | 64 ++++++++++++++++++++++ src/main/java/org/traccar/model/User.java | 17 ------ 7 files changed, 117 insertions(+), 38 deletions(-) create mode 100644 src/main/java/org/traccar/api/signature/TokenManager.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index a689bc236..3b103a6fa 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -32,6 +32,8 @@ + + diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 8eabdc63c..f70b67cde 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 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,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; import org.traccar.api.security.LoginService; +import org.traccar.api.signature.TokenManager; import org.traccar.helper.DataConverter; import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; @@ -40,12 +41,16 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.io.UnsupportedEncodingException; +import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.util.Date; +import java.util.concurrent.TimeUnit; @Path("session") @Produces(MediaType.APPLICATION_JSON) @@ -59,12 +64,15 @@ public class SessionResource extends BaseResource { @Inject private LoginService loginService; - @javax.ws.rs.core.Context + @Inject + private TokenManager tokenManager; + + @Context private HttpServletRequest request; @PermitAll @GET - public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException { + public User get(@QueryParam("token") String token) throws StorageException, IOException, GeneralSecurityException { if (token != null) { User user = loginService.login(token); @@ -84,11 +92,11 @@ public class SessionResource extends BaseResource { for (Cookie cookie : cookies) { if (cookie.getName().equals(USER_COOKIE_KEY)) { byte[] emailBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); email = new String(emailBytes, StandardCharsets.UTF_8); } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { byte[] passwordBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); password = new String(passwordBytes, StandardCharsets.UTF_8); } } @@ -144,4 +152,14 @@ public class SessionResource extends BaseResource { return Response.noContent().build(); } + @Path("token") + @POST + public String requestToken( + @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { + if (expiration == null) { + expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7)); + } + return tokenManager.generateToken(getUserId(), expiration); + } + } diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 104a6fac3..1e82a4cf2 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import org.traccar.api.signature.TokenManager; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; @@ -27,29 +28,35 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import java.io.IOException; +import java.security.GeneralSecurityException; public class LoginService { private final Storage storage; + private final TokenManager tokenManager; private final LdapProvider ldapProvider; private final String serviceAccountToken; private final boolean forceLdap; @Inject - public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { + public LoginService( + Config config, Storage storage, TokenManager tokenManager, @Nullable LdapProvider ldapProvider) { this.storage = storage; + this.tokenManager = tokenManager; this.ldapProvider = ldapProvider; serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); forceLdap = config.getBoolean(Keys.LDAP_FORCE); } - public User login(String token) throws StorageException { + public User login(String token) throws StorageException, GeneralSecurityException, IOException { if (serviceAccountToken != null && serviceAccountToken.equals(token)) { return new ServiceAccountUser(); } + long userId = tokenManager.verifyToken(token); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("token", "token", token))); + new Columns.All(), new Condition.Equals("id", "id", userId))); if (user != null) { checkUserEnabled(user); } diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index ada7bf997..94b6bbf05 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -33,8 +33,10 @@ import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +import java.io.IOException; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; public class SecurityRequestFilter implements ContainerRequestFilter { @@ -94,7 +96,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { statisticsManager.registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); } - } catch (StorageException e) { + } catch (StorageException | GeneralSecurityException | IOException e) { throw new WebApplicationException(e); } diff --git a/src/main/java/org/traccar/api/signature/CryptoManager.java b/src/main/java/org/traccar/api/signature/CryptoManager.java index ea59dcd70..8a3e7704c 100644 --- a/src/main/java/org/traccar/api/signature/CryptoManager.java +++ b/src/main/java/org/traccar/api/signature/CryptoManager.java @@ -15,7 +15,6 @@ */ package org.traccar.api.signature; -import org.traccar.helper.DataConverter; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -46,28 +45,32 @@ public class CryptoManager { this.storage = storage; } - public String sign(String data) throws GeneralSecurityException, StorageException { + public byte[] sign(byte[] data) throws GeneralSecurityException, StorageException { if (privateKey == null) { initializeKeys(); } Signature signature = Signature.getInstance("SHA256withECDSA"); signature.initSign(privateKey); - signature.update(data.getBytes()); - return data + '.' + DataConverter.printBase64(signature.sign()); + signature.update(data); + byte[] block = signature.sign(); + byte[] combined = new byte[1 + block.length + data.length]; + combined[0] = (byte) block.length; + System.arraycopy(block, 0, combined, 1, block.length); + System.arraycopy(data, 0, combined, 1 + block.length, data.length); + return combined; } - public String verify(String data) throws GeneralSecurityException, StorageException { + public byte[] verify(byte[] data) throws GeneralSecurityException, StorageException { if (publicKey == null) { initializeKeys(); } Signature signature = Signature.getInstance("SHA256withECDSA"); signature.initVerify(publicKey); - - int delimiter = data.lastIndexOf('.'); - String originalData = data.substring(0, delimiter); - - signature.update(originalData.getBytes()); - if (!signature.verify(DataConverter.parseBase64(data.substring(delimiter + 1)))) { + int length = data[0]; + byte[] originalData = new byte[data.length - 1 - length]; + System.arraycopy(data, 1 + length, originalData, 0, originalData.length); + signature.update(originalData); + if (!signature.verify(data, 1, length)) { throw new SecurityException("Invalid signature"); } return originalData; diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java new file mode 100644 index 000000000..3f39d5380 --- /dev/null +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -0,0 +1,64 @@ +/* + * 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.api.signature; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.codec.binary.Base64; +import org.traccar.storage.StorageException; + +import javax.inject.Inject; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Date; + +public class TokenManager { + + private final ObjectMapper objectMapper; + private final CryptoManager cryptoManager; + + public static class Data { + @JsonProperty("u") + private long userId; + @JsonProperty("e") + private Date expiration; + } + + @Inject + public TokenManager(ObjectMapper objectMapper, CryptoManager cryptoManager) { + this.objectMapper = objectMapper; + this.cryptoManager = cryptoManager; + } + + public String generateToken( + long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException { + Data data = new Data(); + data.userId = userId; + data.expiration = expiration; + byte[] encoded = objectMapper.writeValueAsBytes(data); + return Base64.encodeBase64URLSafeString(cryptoManager.sign(encoded)); + } + + public long verifyToken(String token) throws IOException, GeneralSecurityException, StorageException { + byte[] encoded = cryptoManager.verify(Base64.decodeBase64(token)); + Data data = objectMapper.readValue(encoded, Data.class); + if (data.expiration.before(new Date())) { + throw new SecurityException("Token has expired"); + } + return data.userId; + } + +} diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 3db20c753..53594fe07 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -208,23 +208,6 @@ public class User extends ExtendedModel implements UserRestrictions, Disableable this.deviceReadonly = deviceReadonly; } - private String token; - - public String getToken() { - return token; - } - - public void setToken(String token) { - if (token != null && !token.isEmpty()) { - if (!token.matches("^[a-zA-Z0-9-]{16,}$")) { - throw new IllegalArgumentException("Illegal token"); - } - this.token = token; - } else { - this.token = null; - } - } - private boolean limitCommands; @Override -- cgit v1.2.3 From 62e4876406de1951705e76f85c1e099c36d48a87 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 20:40:29 -0700 Subject: New tokens for password reset --- .../org/traccar/api/resource/PasswordResource.java | 33 +++++++++++----------- .../org/traccar/api/resource/SessionResource.java | 3 -- .../org/traccar/api/signature/TokenManager.java | 9 +++++- 3 files changed, 25 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 91c2d8ecf..1fb08b02a 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -16,6 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.api.signature.TokenManager; import org.traccar.mail.MailManager; import org.traccar.model.User; import org.traccar.notification.TextTemplateFormatter; @@ -34,35 +35,34 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.UUID; +import java.io.IOException; +import java.security.GeneralSecurityException; @Path("password") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public class PasswordResource extends BaseResource { - private static final String PASSWORD_RESET_TOKEN = "passwordToken"; - @Inject private MailManager mailManager; + @Inject + private TokenManager tokenManager; + @Inject private TextTemplateFormatter textTemplateFormatter; @Path("reset") @PermitAll @POST - public Response reset(@FormParam("email") String email) throws StorageException, MessagingException { + public Response reset(@FormParam("email") String email) + throws StorageException, MessagingException, GeneralSecurityException, IOException { + User user = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("email", "email", email))); if (user != null) { - String token = UUID.randomUUID().toString().replaceAll("-", ""); - user.set(PASSWORD_RESET_TOKEN, token); - storage.updateObject(user, new Request( - new Columns.Include("attributes"), new Condition.Equals("id", "id"))); - var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", token); + velocityContext.put("token", tokenManager.generateToken(user.getId(), null)); var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } @@ -73,15 +73,16 @@ public class PasswordResource extends BaseResource { @PermitAll @POST public Response update( - @FormParam("token") String token, @FormParam("password") String password) throws StorageException { - User user = storage.getObjects(User.class, new Request(new Columns.All())).stream() - .filter(it -> token.equals(it.getString(PASSWORD_RESET_TOKEN))) - .findFirst().orElse(null); + @FormParam("token") String token, @FormParam("password") String password) + throws StorageException, GeneralSecurityException, IOException { + + long userId = tokenManager.verifyToken(token); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", userId))); if (user != null) { - user.getAttributes().remove(PASSWORD_RESET_TOKEN); user.setPassword(password); storage.updateObject(user, new Request( - new Columns.Include("attributes", "hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index f70b67cde..61c3a5885 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -156,9 +156,6 @@ public class SessionResource extends BaseResource { @POST public String requestToken( @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { - if (expiration == null) { - expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7)); - } return tokenManager.generateToken(getUserId(), expiration); } diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java index 3f39d5380..a51234a95 100644 --- a/src/main/java/org/traccar/api/signature/TokenManager.java +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -24,9 +24,12 @@ import javax.inject.Inject; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Date; +import java.util.concurrent.TimeUnit; public class TokenManager { + private static final int DEFAULT_EXPIRATION_DAYS = 7; + private final ObjectMapper objectMapper; private final CryptoManager cryptoManager; @@ -47,7 +50,11 @@ public class TokenManager { long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException { Data data = new Data(); data.userId = userId; - data.expiration = expiration; + if (expiration != null) { + data.expiration = expiration; + } else { + data.expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(DEFAULT_EXPIRATION_DAYS)); + } byte[] encoded = objectMapper.writeValueAsBytes(data); return Base64.encodeBase64URLSafeString(cryptoManager.sign(encoded)); } -- cgit v1.2.3 From bd55a835340547aabc3f401bb97e181a3e70df8f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 20:44:34 -0700 Subject: Remove unused import --- src/main/java/org/traccar/api/resource/SessionResource.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 61c3a5885..05f492d73 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -19,8 +19,8 @@ import org.traccar.api.BaseResource; import org.traccar.api.security.LoginService; import org.traccar.api.signature.TokenManager; import org.traccar.helper.DataConverter; -import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; import org.traccar.model.User; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -44,13 +44,11 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.util.Date; -import java.util.concurrent.TimeUnit; @Path("session") @Produces(MediaType.APPLICATION_JSON) -- cgit v1.2.3 From bb7bdcfc3389b6822b7680837386e3650962f30a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 21:01:06 -0700 Subject: Notifications unsubscribe option --- .../java/org/traccar/api/resource/PasswordResource.java | 2 +- src/main/java/org/traccar/api/signature/TokenManager.java | 4 ++++ .../org/traccar/notification/TextTemplateFormatter.java | 13 ++++++++++++- templates/full/alarm.vm | 4 +++- templates/full/commandResult.vm | 4 +++- templates/full/deviceFuelDrop.vm | 2 ++ templates/full/deviceInactive.vm | 4 +++- templates/full/deviceMoving.vm | 2 ++ templates/full/deviceOffline.vm | 4 +++- templates/full/deviceOnline.vm | 4 +++- templates/full/deviceOverspeed.vm | 2 ++ templates/full/deviceStopped.vm | 2 ++ templates/full/deviceUnknown.vm | 4 +++- templates/full/driverChanged.vm | 4 +++- templates/full/geofenceEnter.vm | 2 ++ templates/full/geofenceExit.vm | 2 ++ templates/full/ignitionOff.vm | 2 ++ templates/full/ignitionOn.vm | 2 ++ templates/full/maintenance.vm | 2 ++ templates/full/media.vm | 4 +++- templates/full/textMessage.vm | 2 ++ 21 files changed, 61 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 1fb08b02a..625ff4cb1 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -62,7 +62,7 @@ public class PasswordResource extends BaseResource { new Columns.All(), new Condition.Equals("email", "email", email))); if (user != null) { var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", tokenManager.generateToken(user.getId(), null)); + velocityContext.put("token", tokenManager.generateToken(user.getId())); var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java index a51234a95..a352ecc10 100644 --- a/src/main/java/org/traccar/api/signature/TokenManager.java +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -46,6 +46,10 @@ public class TokenManager { this.cryptoManager = cryptoManager; } + public String generateToken(long userId) throws IOException, GeneralSecurityException, StorageException { + return generateToken(userId, null); + } + public String generateToken( long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException { Data data = new Data(); diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index bca18f53c..be894af96 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -23,14 +23,18 @@ import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.api.signature.TokenManager; import org.traccar.helper.model.UserUtil; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; +import java.security.GeneralSecurityException; import java.util.Locale; public class TextTemplateFormatter { @@ -38,10 +42,12 @@ public class TextTemplateFormatter { private static final Logger LOGGER = LoggerFactory.getLogger(TextTemplateFormatter.class); private final VelocityEngine velocityEngine; + private final TokenManager tokenManager; @Inject - public TextTemplateFormatter(VelocityEngine velocityEngine) { + public TextTemplateFormatter(VelocityEngine velocityEngine, TokenManager tokenManager) { this.velocityEngine = velocityEngine; + this.tokenManager = tokenManager; } public VelocityContext prepareContext(Server server, User user) { @@ -51,6 +57,11 @@ public class TextTemplateFormatter { if (user != null) { velocityContext.put("user", user); velocityContext.put("timezone", UserUtil.getTimezone(server, user)); + try { + velocityContext.put("token", tokenManager.generateToken(user.getId())); + } catch (IOException | GeneralSecurityException | StorageException e) { + LOGGER.warn("Token generation failed", e); + } } velocityContext.put("webUrl", velocityEngine.getProperty("web.url")); diff --git a/templates/full/alarm.vm b/templates/full/alarm.vm index 8eac3930a..5d367dc3a 100644 --- a/templates/full/alarm.vm +++ b/templates/full/alarm.vm @@ -6,5 +6,7 @@ Device: $device.name
Alarm: $position.getString("alarm")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe - + diff --git a/templates/full/commandResult.vm b/templates/full/commandResult.vm index 443e1a399..c3b62edf5 100644 --- a/templates/full/commandResult.vm +++ b/templates/full/commandResult.vm @@ -5,6 +5,8 @@ Device: $device.name
Result: $position.getString("result")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceFuelDrop.vm b/templates/full/deviceFuelDrop.vm index bf7a16b97..3fb9aa63c 100644 --- a/templates/full/deviceFuelDrop.vm +++ b/templates/full/deviceFuelDrop.vm @@ -5,5 +5,7 @@ Device: $device.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceInactive.vm b/templates/full/deviceInactive.vm index 626db1dc4..01fa319b5 100644 --- a/templates/full/deviceInactive.vm +++ b/templates/full/deviceInactive.vm @@ -7,6 +7,8 @@ Device: $device.name
Inactive
Last Update: $dateTool.format("YYYY-MM-dd HH:mm:ss", $lastUpdate, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceMoving.vm b/templates/full/deviceMoving.vm index b22b90428..e3941b324 100644 --- a/templates/full/deviceMoving.vm +++ b/templates/full/deviceMoving.vm @@ -6,5 +6,7 @@ Device: $device.name
Moving
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceOffline.vm b/templates/full/deviceOffline.vm index 332bfe3d9..8f2c515b2 100644 --- a/templates/full/deviceOffline.vm +++ b/templates/full/deviceOffline.vm @@ -5,6 +5,8 @@ Device: $device.name
Offline
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceOnline.vm b/templates/full/deviceOnline.vm index 3ca3cfa9b..81a4ccbc8 100644 --- a/templates/full/deviceOnline.vm +++ b/templates/full/deviceOnline.vm @@ -5,6 +5,8 @@ Device: $device.name
Online
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceOverspeed.vm b/templates/full/deviceOverspeed.vm index f303b734c..5f38b3f88 100644 --- a/templates/full/deviceOverspeed.vm +++ b/templates/full/deviceOverspeed.vm @@ -15,5 +15,7 @@ Device: $device.name
Exceeds the speed: $speedString#{if}($geofence) in $geofence.name#{else}#{end}
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceStopped.vm b/templates/full/deviceStopped.vm index 9f8a30707..e3246b277 100644 --- a/templates/full/deviceStopped.vm +++ b/templates/full/deviceStopped.vm @@ -6,5 +6,7 @@ Device: $device.name
Stopped
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceUnknown.vm b/templates/full/deviceUnknown.vm index 0e6e9b4b4..e012845e6 100644 --- a/templates/full/deviceUnknown.vm +++ b/templates/full/deviceUnknown.vm @@ -5,6 +5,8 @@ Device: $device.name
Status is unknown
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/driverChanged.vm b/templates/full/driverChanged.vm index 65e2768b5..f9b6d0ae2 100644 --- a/templates/full/driverChanged.vm +++ b/templates/full/driverChanged.vm @@ -5,6 +5,8 @@ Device: $device.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
-Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end} +Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end}
+
+Unsubscribe diff --git a/templates/full/geofenceEnter.vm b/templates/full/geofenceEnter.vm index 2d9cd3613..5ae14a8d3 100644 --- a/templates/full/geofenceEnter.vm +++ b/templates/full/geofenceEnter.vm @@ -6,5 +6,7 @@ Device: $device.name
Has entered geofence: $geofence.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/geofenceExit.vm b/templates/full/geofenceExit.vm index ae1eb5520..08887a93a 100644 --- a/templates/full/geofenceExit.vm +++ b/templates/full/geofenceExit.vm @@ -6,5 +6,7 @@ Device: $device.name
Has exited geofence: $geofence.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/ignitionOff.vm b/templates/full/ignitionOff.vm index 0ec50918b..a43e4aabb 100644 --- a/templates/full/ignitionOff.vm +++ b/templates/full/ignitionOff.vm @@ -6,5 +6,7 @@ Device: $device.name
Ignition OFF
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/ignitionOn.vm b/templates/full/ignitionOn.vm index 7e0d6532d..1ba9ef030 100644 --- a/templates/full/ignitionOn.vm +++ b/templates/full/ignitionOn.vm @@ -6,5 +6,7 @@ Device: $device.name
Ignition ON
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/maintenance.vm b/templates/full/maintenance.vm index 798de637d..39ccb21bc 100644 --- a/templates/full/maintenance.vm +++ b/templates/full/maintenance.vm @@ -6,5 +6,7 @@ Device: $device.name
Maintenance is required: $maintenance.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/media.vm b/templates/full/media.vm index 6651deffc..1c94265fb 100644 --- a/templates/full/media.vm +++ b/templates/full/media.vm @@ -6,6 +6,8 @@ Device: $device.name
Type: $event.getString("media")
File: $event.getString("file")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/textMessage.vm b/templates/full/textMessage.vm index 7222b4d91..fb20275e3 100644 --- a/templates/full/textMessage.vm +++ b/templates/full/textMessage.vm @@ -5,5 +5,7 @@ Device: $device.name
Message: $event.getString("message")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
+
+Unsubscribe -- cgit v1.2.3 From 38961efd25373f290bb20780f770d17b425de88c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 08:35:57 -0700 Subject: Implement GPX export (fix #4646) --- .../org/traccar/api/resource/PositionResource.java | 22 +++++++ .../org/traccar/reports/GpxExportProvider.java | 76 ++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 src/main/java/org/traccar/reports/GpxExportProvider.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index b4c8d18b9..7d7921085 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -21,6 +21,7 @@ import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; import org.traccar.reports.CsvExportProvider; +import org.traccar.reports.GpxExportProvider; import org.traccar.reports.KmlExportProvider; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -54,6 +55,9 @@ public class PositionResource extends BaseResource { @Inject private CsvExportProvider csvExportProvider; + @Inject + private GpxExportProvider gpxExportProvider; + @GET public Collection getJson( @QueryParam("deviceId") long deviceId, @QueryParam("id") List positionIds, @@ -118,4 +122,22 @@ public class PositionResource extends BaseResource { .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.csv").build(); } + @Path("gpx") + @GET + @Produces("application/gpx+xml") + public Response getGpx( + @QueryParam("deviceId") long deviceId, + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + StreamingOutput stream = output -> { + try { + gpxExportProvider.generate(output, deviceId, from, to); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.gpx").build(); + } + } diff --git a/src/main/java/org/traccar/reports/GpxExportProvider.java b/src/main/java/org/traccar/reports/GpxExportProvider.java new file mode 100644 index 000000000..f1a0f292d --- /dev/null +++ b/src/main/java/org/traccar/reports/GpxExportProvider.java @@ -0,0 +1,76 @@ +/* + * 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.reports; + +import org.traccar.helper.DateUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Date; + +public class GpxExportProvider { + + private final Storage storage; + + @Inject + public GpxExportProvider(Storage storage) { + this.storage = storage; + } + + public void generate( + OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { + + var device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + + try (PrintWriter writer = new PrintWriter(outputStream)) { + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(device.getName()); + writer.print(""); + writer.print(""); + positions.forEach(position -> { + writer.print(""); + writer.print(""); + writer.print(position.getAltitude()); + writer.print(""); + writer.print(""); + writer.print(""); + }); + writer.print(""); + writer.print(""); + writer.print(""); + } + } + +} -- cgit v1.2.3 From 45cec80f310c966b63388b18a773533d0e9b9102 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 16:57:14 -0700 Subject: Fix index usage --- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index d8a753abe..3ff8eb2fb 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -239,7 +239,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { private Object decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; + int endIndex = (buf.readUnsignedShortLE() & 0x7fff) + buf.readerIndex(); List positions = new LinkedList<>(); Set tags = new HashSet<>(); @@ -248,7 +248,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; Position position = new Position(getProtocolName()); - while (buf.readerIndex() < length) { + while (buf.readerIndex() < endIndex) { int tag = buf.readUnsignedByte(); if (tags.contains(tag)) { -- cgit v1.2.3 From 3e6929ff362d53aea19516cb5b903d1d753e8ddc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 17:22:26 -0700 Subject: Add GalileoSky Iridium format --- .../traccar/protocol/GalileoProtocolDecoder.java | 40 ++++++++++++++++++++-- .../protocol/GalileoProtocolDecoderTest.java | 3 ++ 2 files changed, 41 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 3ff8eb2fb..b1deded3b 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BitUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -229,7 +230,11 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { int header = buf.readUnsignedByte(); if (header == 0x01) { - return decodePositions(channel, remoteAddress, buf); + if (buf.getUnsignedMedium(buf.readerIndex() + 2) == 0x01001c) { + return decodeIridiumPosition(channel, remoteAddress, buf); + } else { + return decodePositions(channel, remoteAddress, buf); + } } else if (header == 0x07) { return decodePhoto(channel, remoteAddress, buf); } @@ -237,7 +242,38 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + private Position decodeIridiumPosition(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + buf.readUnsignedShortLE(); // length + + buf.skipBytes(3); // identification header + buf.readUnsignedIntLE(); // index + + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readUnsignedByte(); // session status + buf.skipBytes(4); // reserved + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + + buf.skipBytes(3); // coordinates header + int flags = buf.readUnsignedByte(); + double latitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; + double longitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; + position.setLatitude(BitUtil.check(flags, 1) ? -latitude : latitude); + position.setLongitude(BitUtil.check(flags, 0) ? -longitude : longitude); + position.setAccuracy(buf.readUnsignedIntLE()); + + return position; + } + + private List decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int endIndex = (buf.readUnsignedShortLE() & 0x7fff) + buf.readerIndex(); diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index f9bdd6b42..f676b1cc1 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new GalileoProtocolDecoder(null)); + verifyNotNull(decoder, binary( + "01006501001c05cf1f8133303032333430363939303130313000004a000062d8f3ee03000b000f85402088970000000602003503333030323334303639393031303130100000207af3d862300cbe08ee00acfaf001330000760634b301350840090a416b2f42920e")); + verifyPositions(decoder, binary( "011801018202130338363833343530333230343234323604640010a406207caa9f5b300c830a7901ca0ec802330000000034b802350540003e41703f422b1043234504004600e09000000000a000a100a200a300a400a500a600a700a800a900aa00ab00ac00ad00ae00af00b00000b10000b20000b30000b40000b50000b60000b70000b80000b90000c000000000c100000000c200000000c300000000c400c500c600c700c800c900ca00cb00cc00cd00ce00cf00d000d100d200d4d3140000d60000d70000d80000d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000f400000000f500000000f600000000f700000000f800000000f9000000008960")); -- cgit v1.2.3 From 6d1923bd6b4841eac9d1a383e1eafe6cab30ce8c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 18:50:54 -0700 Subject: Rename fuel event handler --- src/main/java/org/traccar/BasePipelineFactory.java | 4 +- .../handler/events/FuelDropEventHandler.java | 71 ---------------------- .../traccar/handler/events/FuelEventHandler.java | 71 ++++++++++++++++++++++ 3 files changed, 73 insertions(+), 73 deletions(-) delete mode 100644 src/main/java/org/traccar/handler/events/FuelDropEventHandler.java create mode 100644 src/main/java/org/traccar/handler/events/FuelEventHandler.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index fb48f81d1..0d91ec7e4 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -45,7 +45,7 @@ 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.FuelEventHandler; import org.traccar.handler.events.GeofenceEventHandler; import org.traccar.handler.events.IgnitionEventHandler; import org.traccar.handler.events.MaintenanceEventHandler; @@ -146,7 +146,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { CommandResultEventHandler.class, OverspeedEventHandler.class, BehaviorEventHandler.class, - FuelDropEventHandler.class, + FuelEventHandler.class, MotionEventHandler.class, GeofenceEventHandler.class, AlertEventHandler.class, diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java deleted file mode 100644 index 25ae1fadb..000000000 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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. - * 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.handler.events; - -import io.netty.channel.ChannelHandler; -import org.traccar.config.Keys; -import org.traccar.helper.model.AttributeUtil; -import org.traccar.helper.model.PositionUtil; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.session.cache.CacheManager; - -import javax.inject.Inject; -import java.util.Collections; -import java.util.Map; - -@ChannelHandler.Sharable -public class FuelDropEventHandler extends BaseEventHandler { - - private final CacheManager cacheManager; - - @Inject - public FuelDropEventHandler(CacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - @Override - protected Map analyzePosition(Position position) { - - Device device = cacheManager.getObject(Device.class, position.getDeviceId()); - if (device == null) { - return null; - } - if (!PositionUtil.isLatest(cacheManager, position)) { - return null; - } - - double fuelDropThreshold = AttributeUtil.lookup( - cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); - if (fuelDropThreshold > 0) { - Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (position.hasAttribute(Position.KEY_FUEL_LEVEL) - && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { - - double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) - - position.getDouble(Position.KEY_FUEL_LEVEL); - if (drop >= fuelDropThreshold) { - Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); - return Collections.singletonMap(event, position); - } - } - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java new file mode 100644 index 000000000..9ec819a5f --- /dev/null +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -0,0 +1,71 @@ +/* + * 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. + * 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.handler.events; + +import io.netty.channel.ChannelHandler; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; + +@ChannelHandler.Sharable +public class FuelEventHandler extends BaseEventHandler { + + private final CacheManager cacheManager; + + @Inject + public FuelEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + @Override + protected Map analyzePosition(Position position) { + + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); + if (device == null) { + return null; + } + if (!PositionUtil.isLatest(cacheManager, position)) { + return null; + } + + double fuelDropThreshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); + if (fuelDropThreshold > 0) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + if (position.hasAttribute(Position.KEY_FUEL_LEVEL) + && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { + + double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) + - position.getDouble(Position.KEY_FUEL_LEVEL); + if (drop >= fuelDropThreshold) { + Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); + return Collections.singletonMap(event, position); + } + } + } + + return null; + } + +} -- cgit v1.2.3 From 074cc52c3d645ac974a1489aa4e197d471093403 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 19:06:12 -0700 Subject: Implement refuel events --- src/main/java/org/traccar/config/Keys.java | 9 +++++++ .../traccar/handler/events/FuelEventHandler.java | 28 +++++++++++++--------- src/main/java/org/traccar/model/Event.java | 1 + templates/full/deviceFuelIncrease.vm | 11 +++++++++ templates/short/deviceFuelIncrease.vm | 2 ++ 5 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 templates/full/deviceFuelIncrease.vm create mode 100644 templates/short/deviceFuelIncrease.vm (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e97e104a1..a3b39581d 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -309,6 +309,15 @@ public final class Keys { List.of(KeyType.SERVER, KeyType.DEVICE), 0.0); + /** + * Fuel increase threshold value. When fuel level increases from one position to another for more the value, an + * event is generated. + */ + public static final ConfigKey EVENT_FUEL_INCREASE_THRESHOLD = new DoubleConfigKey( + "fuelIncreaseThreshold", + List.of(KeyType.SERVER, KeyType.DEVICE), + 0.0); + /** * Speed limit value in knots. */ diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java index 9ec819a5f..d5d4ab9be 100644 --- a/src/main/java/org/traccar/handler/events/FuelEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -25,7 +25,6 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; -import java.util.Collections; import java.util.Map; @ChannelHandler.Sharable @@ -49,18 +48,25 @@ public class FuelEventHandler extends BaseEventHandler { return null; } - double fuelDropThreshold = AttributeUtil.lookup( - cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); - if (fuelDropThreshold > 0) { + if (position.hasAttribute(Position.KEY_FUEL_LEVEL)) { Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (position.hasAttribute(Position.KEY_FUEL_LEVEL) - && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { + if (lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { + double before = lastPosition.getDouble(Position.KEY_FUEL_LEVEL); + double after = position.getDouble(Position.KEY_FUEL_LEVEL); + double change = after - before; - double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) - - position.getDouble(Position.KEY_FUEL_LEVEL); - if (drop >= fuelDropThreshold) { - Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); - return Collections.singletonMap(event, position); + if (change > 0) { + double threshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_INCREASE_THRESHOLD, position.getDeviceId()); + if (change >= threshold) { + return Map.of(new Event(Event.TYPE_DEVICE_FUEL_INCREASE, position), position); + } + } else if (change < 0) { + double threshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); + if (Math.abs(change) >= threshold) { + return Map.of(new Event(Event.TYPE_DEVICE_FUEL_DROP, position), position); + } } } } diff --git a/src/main/java/org/traccar/model/Event.java b/src/main/java/org/traccar/model/Event.java index f00a0e5f1..0e851d748 100644 --- a/src/main/java/org/traccar/model/Event.java +++ b/src/main/java/org/traccar/model/Event.java @@ -52,6 +52,7 @@ public class Event extends Message { public static final String TYPE_DEVICE_OVERSPEED = "deviceOverspeed"; public static final String TYPE_DEVICE_FUEL_DROP = "deviceFuelDrop"; + public static final String TYPE_DEVICE_FUEL_INCREASE = "deviceFuelIncrease"; public static final String TYPE_GEOFENCE_ENTER = "geofenceEnter"; public static final String TYPE_GEOFENCE_EXIT = "geofenceExit"; diff --git a/templates/full/deviceFuelIncrease.vm b/templates/full/deviceFuelIncrease.vm new file mode 100644 index 000000000..9d4474e1a --- /dev/null +++ b/templates/full/deviceFuelIncrease.vm @@ -0,0 +1,11 @@ +#set($subject = "$device.name: fuel increase") + + + +Device: $device.name
+Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
+Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe + + diff --git a/templates/short/deviceFuelIncrease.vm b/templates/short/deviceFuelIncrease.vm new file mode 100644 index 000000000..6a11418b1 --- /dev/null +++ b/templates/short/deviceFuelIncrease.vm @@ -0,0 +1,2 @@ +#set($subject = "$device.name: fuel increase") +$device.name fuel increase at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) -- cgit v1.2.3 From dbc5fc5dcf697dcc00d357bbca5fe4669325148b Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 6 Aug 2022 17:42:22 +0100 Subject: Updated Xexun2 Protocol --- src/main/java/org/traccar/helper/Checksum.java | 8 +--- .../org/traccar/protocol/Xexun2FrameEncoder.java | 48 ++++++++++++++++++++++ .../java/org/traccar/protocol/Xexun2Protocol.java | 1 + .../traccar/protocol/Xexun2ProtocolDecoder.java | 12 +++--- .../traccar/protocol/Xexun2ProtocolEncoder.java | 48 ++++------------------ .../traccar/protocol/Xexun2FrameDecoderTest.java | 4 ++ .../traccar/protocol/Xexun2FrameEncoderTest.java | 20 +++++++++ 7 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java create mode 100644 src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/Checksum.java b/src/main/java/org/traccar/helper/Checksum.java index e660790ef..db5817275 100644 --- a/src/main/java/org/traccar/helper/Checksum.java +++ b/src/main/java/org/traccar/helper/Checksum.java @@ -200,18 +200,14 @@ public final class Checksum { return (10 - (checksum % 10)) % 10; } - public static int udp(ByteBuffer data) { + public static int ip(ByteBuffer data) { int sum = 0; - int len = data.capacity(); - for (int j = 0; len > 1; len--) { + while (data.remaining() > 0) { sum += data.get() & 0xff; if ((sum & 0x80000000) > 0) { sum = (sum & 0xffff) + (sum >> 16); } } - if (len == 1) { - sum += data.get() & 0xff; - } while ((sum >> 16) > 0) { sum = (sum & 0xffff) + sum >> 16; } diff --git a/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java new file mode 100644 index 000000000..52d43c36c --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) + * + * 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.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class Xexun2FrameEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { + out.writeBytes(msg.readBytes(2)); + + while (msg.readableBytes() > 2) { + int b = msg.readUnsignedByte(); + if (b == 0xfa && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xaf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x01); + } else if (b == 0xfb && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xbf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x02); + } else { + out.writeByte(b); + } + } + + out.writeBytes(msg.readBytes(2)); + + } +} diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 1d5038a22..52cf731f0 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -35,6 +35,7 @@ public class Xexun2Protocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new Xexun2FrameEncoder()); pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); pipeline.addLast(new Xexun2ProtocolEncoder(Xexun2Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index f0158e6ce..913dfaf28 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,12 +42,14 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int FLAG = 0xfaaf; + public static final int MSG_COMMAND = 0x07; public static final int MSG_POSITION = 0x14; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { ByteBuf response = Unpooled.buffer(); - response.writeShort(Xexun2ProtocolEncoder.FLAG); + response.writeShort(FLAG); response.writeShort(type); response.writeShort(index); @@ -56,7 +58,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0xfffe); // checksum response.writeByte(1); // response - response.writeShort(Xexun2ProtocolEncoder.FLAG); + response.writeShort(FLAG); channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } @@ -99,13 +101,13 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } int payloadSize = buf.readUnsignedShort() & 0x03ff; - int checksum = buf.readUnsignedShort(); // checksum + int checksum = buf.readUnsignedShort(); - if (checksum != Checksum.udp(buf.nioBuffer(buf.readerIndex(), payloadSize))) { + if (checksum != Checksum.ip(buf.nioBuffer(buf.readerIndex(), payloadSize))) { return null; } - if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { + if (type != MSG_COMMAND) { sendResponse(channel, type, index, imei); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index 6e1e1d68d..c315cab30 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -23,61 +23,29 @@ import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; +import java.nio.charset.StandardCharsets; + public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { public Xexun2ProtocolEncoder(Protocol protocol) { super(protocol); } - public static final int FLAG = 0xfaaf; - public static final int MSG_COMMAND = 0x07; - - private static ByteBuf encodeFrame(ByteBuf buf) { - int bufLength = buf.readableBytes(); - if (bufLength < 5) { - return null; - } - - ByteBuf result = Unpooled.buffer(); - - result.writeBytes(buf.readBytes(2)); - - while (buf.readerIndex() < bufLength - 2) { - int b = buf.readUnsignedByte(); - if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { - buf.readUnsignedByte(); - result.writeByte(0xfb); - result.writeByte(0xbf); - result.writeByte(0x01); - } else if (b == 0xfb && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { - buf.readUnsignedByte(); - result.writeByte(0xfb); - result.writeByte(0xbf); - result.writeByte(0x02); - } else { - result.writeByte(b); - } - } - result.writeBytes(buf.readBytes(2)); - - return result; - } - private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); - ByteBuf message = Unpooled.copiedBuffer(content.getBytes()); + ByteBuf message = Unpooled.copiedBuffer(content.getBytes(StandardCharsets.US_ASCII)); - buf.writeShort(FLAG); - buf.writeShort(MSG_COMMAND); + buf.writeShort(Xexun2ProtocolDecoder.FLAG); + buf.writeShort(Xexun2ProtocolDecoder.MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.capacity()); - buf.writeShort(Checksum.udp(message.nioBuffer())); + buf.writeShort(Checksum.ip(message.nioBuffer())); buf.writeBytes(message); - buf.writeShort(FLAG); + buf.writeShort(Xexun2ProtocolDecoder.FLAG); - return encodeFrame(buf); + return buf; } @Override diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java index 7209a423b..34437862c 100644 --- a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java @@ -14,6 +14,10 @@ public class Xexun2FrameDecoderTest extends ProtocolTest { binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"), decoder.decode(null, null, binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"))); + verifyFrame( + binary("FAAF123456FAAF123456FBBF123456FAAF"), + decoder.decode(null, null, binary("FAAF123456FBBF01123456FBBF02123456FAAF"))); + } } diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java new file mode 100644 index 000000000..54a8aaa14 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java @@ -0,0 +1,20 @@ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Xexun2FrameEncoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Xexun2FrameEncoder encoder = new Xexun2FrameEncoder(); + + ByteBuf result = Unpooled.buffer(); + encoder.encode(null, binary("FAAF123456FAAF123456FBBF123456FAAF"), result); + verifyFrame(binary("FAAF123456FBBF01123456FBBF02123456FAAF"), result); + } + +} -- cgit v1.2.3 From 890ecacae6a442ae2b8d4a0e0e2acd4f3e052135 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 20:29:27 -0700 Subject: Handle unknown device (fix #4917) --- src/main/java/org/traccar/protocol/WondexProtocolDecoder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java index 22d7bade3..46aa65a5d 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -74,6 +74,9 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder { || buf.toString(StandardCharsets.US_ASCII).startsWith("$MSG:")) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -89,12 +92,12 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.setTime(parser.nextDateTime()); -- cgit v1.2.3 From 18799d894619683cbffbbd140648737abd8b4cc5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 21:47:07 -0700 Subject: Handle API 404 errors --- src/main/java/org/traccar/web/WebServer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 704a4b3cd..62ac338eb 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -106,7 +106,8 @@ public class WebServer implements LifecycleObject { protected void handleErrorPage( HttpServletRequest request, Writer writer, int code, String message) throws IOException { Path index = Paths.get(config.getString(Keys.WEB_PATH), "index.html"); - if (code == HttpStatus.NOT_FOUND_404 && Files.exists(index)) { + if (code == HttpStatus.NOT_FOUND_404 + && !request.getPathInfo().startsWith("/api/") && Files.exists(index)) { writer.write(Files.readString(index)); } else { writer.write("Error" -- cgit v1.2.3 From a551ac40761520e8d48e4438213f70854569c1d9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 16:53:12 -0700 Subject: Fix Iridium decoding --- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index b1deded3b..1f6a4d2b4 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -262,7 +262,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(4); // reserved position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - buf.skipBytes(3); // coordinates header + buf.skipBytes(2); // coordinates header int flags = buf.readUnsignedByte(); double latitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; double longitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; -- 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 'src/main/java/org') 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 90a6ae2affe642ced72a6a47fa0e0f919cbaeba3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 17:51:53 -0700 Subject: Remove empty comment lines --- src/main/java/org/traccar/config/Keys.java | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index a3b39581d..e6c3656da 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1168,7 +1168,6 @@ public final class Keys { * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if Position * appears valid or if Position `speed` field reported by the device is also within limits. Calculates speed from * the distance to the previous position and the elapsed time. - * * Tip: Shouldn't be too low. Start testing with values at about 25000. */ public static final ConfigKey FILTER_MAX_SPEED = new IntegerConfigKey( @@ -1185,7 +1184,6 @@ public final class Keys { /** * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, * distance, speed, or time period only against the location that was last received by server. - * * If true, the server expects locations to come at random order (since tracking device might go offline). * Filter checks for duplicates, distance, speed, or time period against the preceding Position's. * Important: setting to true can cause potential performance issues. @@ -1229,7 +1227,6 @@ public final class Keys { /** * List of protocols to enable. If not specified, Traccar enabled all protocols that have port numbers listed. * The value is a comma-separated list of protocol names. - * * Example value: teltonika,osmand */ public static final ConfigKey PROTOCOLS_ENABLE = new StringConfigKey( @@ -1522,7 +1519,6 @@ public final class Keys { /** * Public URL for the web app. Used for notification and report link. - * * If not provided, Traccar will attempt to get a URL from the server IP address, but it might be a local address. */ public static final ConfigKey WEB_URL = new StringConfigKey( -- cgit v1.2.3 From 48a703302a8213402d5225d0087abc13521410a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 18:30:56 -0700 Subject: Remove trailing URL slash --- src/main/java/org/traccar/MainModule.java | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b8ff21472..e0617a734 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -318,17 +318,19 @@ public class MainModule extends AbstractModule { properties.setProperty("file.resource.loader.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); properties.setProperty("runtime.log.logsystem.class", NullLogChute.class.getName()); - String address; - try { - address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; + if (config.hasKey(Keys.WEB_URL)) { + properties.setProperty("web.url", config.getString(Keys.WEB_URL).replaceAll("/$", "")); + } else { + String address; + try { + address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + String url = URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); + properties.setProperty("web.url", url); } - String url = config.getString( - Keys.WEB_URL, URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", "")); - properties.setProperty("web.url", url); - VelocityEngine velocityEngine = new VelocityEngine(); velocityEngine.init(properties); return velocityEngine; -- cgit v1.2.3 From d8607eb0e840df9df7006f7ae2a15b8b082bf7bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:07:31 -0700 Subject: Support Suntech ignition --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 52fdaa05c..f1097abac 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -570,7 +570,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 17)) { - position.set(Position.KEY_INPUT, Integer.parseInt(values[index++])); + int input = Integer.parseInt(values[index++]); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); + position.set(Position.KEY_INPUT, input); } if (BitUtil.check(mask, 18)) { -- cgit v1.2.3 From 8cb215e3426f948802f82cbd22dfddcac45d5ef0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:11:56 -0700 Subject: Use GT06 declared types --- src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index e1c17710b..6b2cd6833 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -44,7 +44,7 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { buf.writeByte(1 + 1 + 4 + content.length() + 2 + 2 + (language ? 2 : 0)); // message length - buf.writeByte(0x80); // message type + buf.writeByte(Gt06ProtocolDecoder.MSG_COMMAND_0); buf.writeByte(4 + content.length()); // command length buf.writeInt(0); -- cgit v1.2.3 From 8a7275a8680ca0db4def3b4c52ad1ddcf4525949 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:37:08 -0700 Subject: Handle calendar caching --- .../org/traccar/session/cache/CacheManager.java | 41 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 07f27d776..6f6b648fa 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -20,6 +20,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; +import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -28,6 +29,7 @@ import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; +import org.traccar.model.ScheduledModel; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; @@ -218,6 +220,10 @@ public class CacheManager implements BroadcastInterface { if (((GroupedModel) before).getGroupId() != ((GroupedModel) object).getGroupId()) { invalidate = true; } + } else if (object instanceof ScheduledModel) { + if (((ScheduledModel) before).getCalendarId() != ((ScheduledModel) object).getCalendarId()) { + invalidate = true; + } } if (invalidate) { invalidate(object.getClass(), object.getId()); @@ -294,7 +300,19 @@ public class CacheManager implements BroadcastInterface { var objects = storage.getObjects(clazz, new Request( new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toSet())); - objects.forEach(object -> addObject(deviceId, object)); + for (var object : objects) { + addObject(deviceId, object); + if (object instanceof ScheduledModel) { + var scheduled = (ScheduledModel) object; + if (scheduled.getCalendarId() > 0) { + var calendar = storage.getObject(Calendar.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", scheduled.getCalendarId()))); + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) + .add(calendar.getId()); + addObject(deviceId, calendar); + } + } + } } var users = storage.getObjects(User.class, new Request( @@ -303,13 +321,22 @@ public class CacheManager implements BroadcastInterface { for (var user : users) { addObject(deviceId, user); var notifications = storage.getObjects(Notification.class, new Request( - new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); - notifications.stream() + new Columns.All(), + new Condition.Permission(User.class, user.getId(), Notification.class))).stream() .filter(Notification::getAlways) - .forEach(object -> { - links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()).add(object.getId()); - addObject(deviceId, object); - }); + .collect(Collectors.toList()); + for (var notification : notifications) { + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) + .add(notification.getId()); + addObject(deviceId, notification); + if (notification.getCalendarId() > 0) { + var calendar = storage.getObject(Calendar.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", notification.getCalendarId()))); + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) + .add(calendar.getId()); + addObject(deviceId, calendar); + } + } } deviceLinks.put(deviceId, links); -- cgit v1.2.3 From 7237e4b515884721058993f2ccb8f06f8333b867 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:38:18 -0700 Subject: Support OsmAnd charging info --- src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index 5f8e7424b..c8968023a 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -143,6 +143,9 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { case "driverUniqueId": position.set(Position.KEY_DRIVER_UNIQUE_ID, value); break; + case "charge": + position.set(Position.KEY_CHARGE, Boolean.parseBoolean(value)); + break; default: try { position.set(entry.getKey(), Double.parseDouble(value)); -- cgit v1.2.3 From 10aba298620884d6f018fe94cda9b1d4d4a9e20f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 13 Aug 2022 06:44:32 -0700 Subject: Fix deprecated --- src/main/java/org/traccar/protocol/IotmProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index 57e4c736f..bdc691d27 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2021 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. @@ -339,7 +339,7 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // checksum MqttMessage response = MqttMessageBuilders.pubAck() - .packetId((short) message.variableHeader().packetId()) + .packetId(message.variableHeader().packetId()) .build(); if (channel != null) { -- cgit v1.2.3 From 812994893d2bdd3e873b1ba27844b713f59e5449 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 13 Aug 2022 06:44:59 -0700 Subject: Fix deprecated --- src/main/java/org/traccar/protocol/IotmProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index bdc691d27..7bbe6c8de 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -260,7 +260,7 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder { MqttSubscribeMessage message = (MqttSubscribeMessage) msg; MqttMessage response = MqttMessageBuilders.subAck() - .packetId((short) message.variableHeader().messageId()) + .packetId(message.variableHeader().messageId()) .build(); if (channel != null) { -- cgit v1.2.3 From d16c01cbefd634e285354bc4a097736644332eba Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 Aug 2022 06:47:32 -0700 Subject: Fix FM11 FM12 FM36 decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 2b1196d55..2476fd384 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -253,8 +253,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(182, null, (p, b) -> p.set(Position.KEY_HDOP, b.readUnsignedShort() * 0.1)); register(199, null, (p, b) -> p.set(Position.KEY_ODOMETER_TRIP, b.readUnsignedInt())); register(200, fmbXXX, (p, b) -> p.set("sleepMode", b.readUnsignedByte())); - register(205, null, (p, b) -> p.set("cid", b.readUnsignedShort())); - register(206, null, (p, b) -> p.set("lac", b.readUnsignedShort())); + register(205, fmbXXX, (p, b) -> p.set("cid", b.readUnsignedShort())); + register(206, fmbXXX, (p, b) -> p.set("lac", b.readUnsignedShort())); register(236, null, (p, b) -> { p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); }); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 0ae4bbfa4..6a13f59c9 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000000e708030000018293d62060000de1f6a62159767e00000000000000000b074504f00050041500c801ef004f630342320043000344000001f100006019000000018291b0c790000de1f6a62159767e006e0144070000ef12074503f00050051505c800ef004f0207b5000eb6000b423324180000ce00dc43001144000004c700000007f100006019cd0003c7776300ea4e2e000000018291aff0b8000de1f91f21597405006f00f61300080012074503f00150051504c800ef014f0207b50009b600054236c1180008ce00dc43003f44000004c700000003f100006019cd0003c7776300ea4e2700030000a48d")); + verifyPositions(decoder, binary( "00000000000000da08030000017fcedf499600280431be0eded45d0038012d100000fa100901000200b300b4004501500415034702fa00054232a1180000cd3b2fce281d43001f02c700000006f10000a029000000017fcedea99600280432070eded3dd00380046130009000f0801010200b300b400450150051502470205423276180009cd3b2fce281d43001f02c700000027f10000a0290000000179d50853180027f65d3f0ed67212001500f1110061000f0801010200b300b4004501500515034702054234f4180061cd53d1ce28c043003e02c700000147f1000000290003000052cb")); -- cgit v1.2.3 From 74a6ec5ff14e4871a0f61d05aa4cec89d0950038 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 Aug 2022 07:54:54 -0700 Subject: Fix FM6320 decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 2476fd384..89124cb22 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -244,7 +244,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { p.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); } }); - register(80, null, (p, b) -> p.set("dataMode", b.readUnsignedByte())); + register(80, fmbXXX, (p, b) -> p.set("dataMode", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); register(115, fmbXXX, (p, b) -> p.set(Position.KEY_COOLANT_TEMP, b.readShort() * 0.1)); register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 6a13f59c9..994a55109 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000003831004000001735ace37f80000e3b9331c71e290006900e211005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005538006e00006f00007a03007d00007f5600890000fd0200fe1f09004326b00044000000b5000b00b6000600427029001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022a1005000000054005400000000005600015568005700000060005800000420006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ca80000e3b08a1c71dd29006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe1d09004326ac0044000000b5000b00b600060042701f001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022ce00500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3fc80000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ffa0000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0300fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000040000eb85")); + verifyPositions(decoder, binary( "00000000000000e708030000018293d62060000de1f6a62159767e00000000000000000b074504f00050041500c801ef004f630342320043000344000001f100006019000000018291b0c790000de1f6a62159767e006e0144070000ef12074503f00050051505c800ef004f0207b5000eb6000b423324180000ce00dc43001144000004c700000007f100006019cd0003c7776300ea4e2e000000018291aff0b8000de1f91f21597405006f00f61300080012074503f00150051504c800ef014f0207b50009b600054236c1180008ce00dc43003f44000004c700000003f100006019cd0003c7776300ea4e2700030000a48d")); -- cgit v1.2.3 From a0e484704bd9b5e046a6940beb7450168b5188df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 Aug 2022 17:39:55 -0700 Subject: Decode minimal data set --- .../traccar/protocol/GalileoProtocolDecoder.java | 42 ++++++++++++++++------ 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 1f6a4d2b4..fc8a49cf5 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,15 +20,16 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.helper.BitUtil; -import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.helper.BitBuffer; 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.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -36,6 +37,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; public class GalileoProtocolDecoder extends BaseProtocolDecoder { @@ -242,6 +244,27 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return null; } + private void decodeMinimalDataSet(Position position, ByteBuf buf) { + BitBuffer bits = new BitBuffer(buf.readSlice(10)); + bits.readUnsigned(1); + + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.set(Calendar.DAY_OF_YEAR, 1); + calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY)); + calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); + calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); + calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); + calendar.add(Calendar.SECOND, bits.readUnsigned(25)); + position.setTime(calendar.getTime()); + + position.setValid(bits.readUnsigned(1) == 0); + position.setLongitude(360 * bits.readUnsigned(22) / 4194304.0 - 180); + position.setLatitude(360 * bits.readUnsigned(21) / 2097152.0 - 90); + if (bits.readUnsigned(1) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + } + private Position decodeIridiumPosition(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedShortLE(); // length @@ -260,15 +283,12 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // session status buf.skipBytes(4); // reserved - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - - buf.skipBytes(2); // coordinates header - int flags = buf.readUnsignedByte(); - double latitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; - double longitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; - position.setLatitude(BitUtil.check(flags, 1) ? -latitude : latitude); - position.setLongitude(BitUtil.check(flags, 0) ? -longitude : longitude); - position.setAccuracy(buf.readUnsignedIntLE()); + buf.readUnsignedIntLE(); // date and time + + buf.skipBytes(23); // coordinates block + + buf.skipBytes(3); // data tag header + decodeMinimalDataSet(position, buf); return position; } -- cgit v1.2.3 From d11002c4820c2f964a9e4c2f1bdc8b758bfa7050 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 Aug 2022 17:59:38 -0700 Subject: Add Mobicom driving behavior --- .../traccar/protocol/HuabaoProtocolDecoder.java | 38 +++++++++++++++++++++- .../protocol/HuabaoProtocolDecoderTest.java | 4 +++ 2 files changed, 41 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index b891bc388..5393c6f74 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -490,7 +490,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); break; case 0xD4: - case 0xFE: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; case 0xD5: @@ -561,6 +560,43 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0xFE: + if (length == 1) { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } else { + int mark = buf.readUnsignedByte(); + if (mark == 0x7C) { + while (buf.readerIndex() < endIndex) { + int extendedType = buf.readUnsignedByte(); + int extendedLength = buf.readUnsignedByte(); + switch (extendedType) { + case 0x01: + long alarms = buf.readUnsignedInt(); + if (BitUtil.check(alarms, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + } + if (BitUtil.check(alarms, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + } + if (BitUtil.check(alarms, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + } + if (BitUtil.check(alarms, 3)) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + } + if (BitUtil.check(alarms, 4)) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + break; + default: + buf.skipBytes(extendedLength); + break; + } + } + } + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } + break; default: break; } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 49622745f..7322185d5 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), + Position.KEY_ALARM, Position.ALARM_ACCELERATION); + verifyAttribute(decoder, binary( "7e020000340551231425560568000000000400000201618a9706c320e100410000002722060816261501040000015d300115310105eb0a000300e164000300e301957e"), Position.KEY_BATTERY_LEVEL, 100); -- cgit v1.2.3 From 6bce58763ef9b8ba3b75139114f727c5685694d0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 17 Aug 2022 06:29:07 -0700 Subject: Correct G109 command format --- .../org/traccar/protocol/Gt06ProtocolEncoder.java | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 6b2cd6833..dc5dd446f 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.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. @@ -23,6 +23,7 @@ import org.traccar.config.Keys; import org.traccar.helper.Checksum; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.model.Device; import java.nio.charset.StandardCharsets; @@ -73,13 +74,25 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { String password = AttributeUtil.getDevicePassword( getCacheManager(), command.getDeviceId(), getProtocolName(), "123456"); + Device device = getCacheManager().getObject(Device.class, command.getDeviceId()); + switch (command.getType()) { case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), - alternative ? "DYD," + password + "#" : "Relay,1#"); + if ("G109".equals(device.getModel())) { + return encodeContent(command.getDeviceId(), "DYD#"); + } else if (alternative) { + return encodeContent(command.getDeviceId(), "DYD," + password + "#"); + } else { + return encodeContent(command.getDeviceId(), "Relay,1#"); + } case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), - alternative ? "HFYD," + password + "#" : "Relay,0#"); + if ("G109".equals(device.getModel())) { + return encodeContent(command.getDeviceId(), "HFYD#"); + } else if (alternative) { + return encodeContent(command.getDeviceId(), "HFYD," + password + "#"); + } else { + return encodeContent(command.getDeviceId(), "Relay,0#"); + } case Command.TYPE_CUSTOM: return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); default: -- cgit v1.2.3 From 3899dddebcee96b80d5c939f50b846ef5042a7ff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 18 Aug 2022 16:22:42 -0700 Subject: Firebase include event id --- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index ecf3fbb70..6510963c7 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -80,6 +80,7 @@ public class NotificatorFirebase implements Notificator { .build()) .build()) .addAllTokens(registrationTokens) + .putData("eventId", String.valueOf(event.getId())) .build(); try { -- cgit v1.2.3 From 1fb6c86ea12f325bfdb372d98400c8a904c6e927 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 20 Aug 2022 09:00:27 -0700 Subject: Support TK103 cell info (fix #4925) --- src/main/java/org/traccar/helper/PatternUtil.java | 2 +- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 49 +++++++++++++++++++++- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 6 +++ 3 files changed, 54 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/PatternUtil.java b/src/main/java/org/traccar/helper/PatternUtil.java index 74813e1d9..a46c7b7b4 100644 --- a/src/main/java/org/traccar/helper/PatternUtil.java +++ b/src/main/java/org/traccar/helper/PatternUtil.java @@ -63,7 +63,7 @@ public final class PatternUtil { for (int i = 0; i < pattern.length(); i++) { try { - Matcher matcher = Pattern.compile("(" + pattern.substring(0, i) + ").*").matcher(input); + Matcher matcher = Pattern.compile("(" + pattern.substring(0, i) + ")[\\s\\S]*").matcher(input); if (matcher.matches()) { result.patternMatch = pattern.substring(0, i); result.patternTail = pattern.substring(i); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index e197a8a41..b343c3b33 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -99,6 +99,16 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_CELL = new PatternBuilder() + .text("(") + .number("(d{12})") // device id + .expression(".{4}") // type + .number("(?:d{15})?,") // imei + .expression("(.+),") // cell + .number("(d{8})") // odometer + .text(")") + .compile(); + private static final Pattern PATTERN_NETWORK = new PatternBuilder() .text("(").optional() .number("(d{12})") // device id @@ -297,6 +307,39 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeCell(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_CELL, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + Network network = new Network(); + + String[] cells = parser.next().split("\n"); + for (String cell : cells) { + String[] values = cell.substring(1, cell.length() - 1).split(","); + network.addCellTower(CellTower.from( + Integer.parseInt(values[0]), Integer.parseInt(values[1]), + Integer.parseInt(values[2]), Integer.parseInt(values[3]))); + } + + position.setNetwork(network); + + position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); + + return position; + } + private Position decodeNetwork(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_NETWORK, sentence); if (!parser.matches()) { @@ -422,7 +465,9 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { } } - if (sentence.contains("ZC20")) { + if (sentence.indexOf('{') > 0 && sentence.indexOf('}') > 0) { + return decodeCell(channel, remoteAddress, sentence); + } else if (sentence.contains("ZC20")) { return decodeBattery(channel, remoteAddress, sentence); } else if (sentence.contains("BZ00")) { return decodeNetwork(channel, remoteAddress, sentence); diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 6c01c14f7..8b3177136 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Tk103ProtocolDecoder(null)); + verifyAttributes(decoder, text( + "(027046434858BZ00,{460,0,20949,58711}\n{460,0,20494,54003}\n{460,0,20951,19569}\n,01000000)")); + + verifyAttributes(decoder, text( + "(027045009305BP05355227045009305,{413,2,30073,16724}\n{413,2,30073,16730}\n{413,2,30073,49860}\n,01000000)")); + verifyPosition(decoder, text( "(868822040452227,DW3B,150421,A,4154.51607N,45.78950E,0.050,103142,0.000,595.200,7,0)")); -- cgit v1.2.3 From ae4deabf310135c68e0eab0a47470cf2cdf616a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 23 Aug 2022 16:36:35 -0700 Subject: Support PUBX NMEA messages --- .../org/traccar/protocol/T55ProtocolDecoder.java | 61 +++++++++++++++++++++- .../traccar/protocol/T55ProtocolDecoderTest.java | 3 ++ 2 files changed, 63 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 409c7e768..1529aae29 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -125,6 +125,30 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { .expression("([01])") // ignition .compile(); + private static final Pattern PATTERN_PUBX = new PatternBuilder() + .text("$PUBX,") + .number("(d+),") // index + .number("(dd)(dd)(dd).d+,") // time (hhmmss) + .number("(dd)(dd.d+),([NS]),") // latitude + .number("(ddd)(dd.d+),([EW]),") // longitude + .number("(-?d+.d+),") // altitude + .expression("(..),") // status + .number("(d+.d+),") // horizontal accuracy + .number("d+.d+,") // vertical accuracy + .number("(d+.d+),") // speed + .number("(d+.d+),") // course + .number("-?d+.d+,") // vertical velocity + .expression("[^,]*,") // corrections age + .number("(d+.d+),") // hdop + .number("(d+.d+),") // vdop + .number("d+.d+,") // tdop + .number("(d+),") // satellites + .number("(d+),") // device id + .number("d+") + .text("*") + .number("xx") // checksum + .compile(); + private Position position = null; private Position decodeGprmc( @@ -303,6 +327,39 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodePubx(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_PUBX, sentence); + if (!parser.matches()) { + return null; + } + + Position position = new Position(getProtocolName()); + + position.set(Position.KEY_INDEX, parser.nextInt()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS)); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setAltitude(parser.nextDouble()); + position.setValid(!parser.next().equals("NF")); + position.setAccuracy(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + position.set(Position.KEY_HDOP, parser.nextDouble()); + position.set(Position.KEY_VDOP, parser.nextDouble()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + return position; + } + + return null; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -357,6 +414,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return decodeGpiop(deviceSession, sentence); } else if (sentence.startsWith("QZE")) { return decodeQze(channel, remoteAddress, sentence); + } else if (sentence.startsWith("$PUBX")) { + return decodePubx(channel, remoteAddress, sentence); } return null; diff --git a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java index 6ce47db94..1622f64f2 100644 --- a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class T55ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new T55ProtocolDecoder(null)); + verifyPosition(decoder, text( + "$PUBX,00,130209.00,3650.51159,N,01346.10602,E,785.947,D3,4.1,5.2,0.163,87.43,-0.054,7.0,0.88,1.21,0.88,24,01012,0*6D")); + verifyPosition(decoder, text( "QZE,868994033976700,35,28062020,113553,22.13673,114.57263,0,22,A,0")); -- cgit v1.2.3 From 5b174c67e5433a1ceceddc159ee6db6e229d5ba6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Aug 2022 18:19:35 -0700 Subject: Geofences in events report (fix #4929) --- src/main/java/org/traccar/reports/common/ReportUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 253a6a2b6..7fff46f66 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -93,7 +93,7 @@ public class ReportUtils { public T getObject( long userId, Class clazz, long objectId) throws StorageException, SecurityException { return storage.getObject(clazz, new Request( - new Columns.Include("id"), + new Columns.All(), new Condition.And( new Condition.Equals("id", "id", objectId), new Condition.Permission(User.class, userId, clazz)))); -- cgit v1.2.3 From 4b2102596354446c291540a8c38e7cb4b0dd1086 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 29 Aug 2022 17:03:00 -0700 Subject: Allow saved commands (fix #4932) --- src/main/java/org/traccar/api/resource/CommandResource.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 60f1f8eb0..636b45023 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -97,7 +97,15 @@ public class CommandResource extends ExtendedObjectResource { @Path("send") public Response send(Command entity) throws Exception { permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); - permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); + if (entity.getId() > 0) { + permissionsService.checkPermission(Command.class, getUserId(), entity.getId()); + long deviceId = entity.getDeviceId(); + entity = storage.getObject(baseClass, new Request( + new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + entity.setDeviceId(deviceId); + } else { + permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); + } permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); if (!commandsManager.sendCommand(entity)) { return Response.accepted(entity).build(); -- cgit v1.2.3 From fa78acf7876851e6e15e116ebe25f2f65a28fea0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 5 Sep 2022 10:25:34 -0700 Subject: Return default string value --- src/main/java/org/traccar/notification/PropertiesProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notification/PropertiesProvider.java b/src/main/java/org/traccar/notification/PropertiesProvider.java index 4ffad432c..91887b5d4 100644 --- a/src/main/java/org/traccar/notification/PropertiesProvider.java +++ b/src/main/java/org/traccar/notification/PropertiesProvider.java @@ -37,7 +37,8 @@ public class PropertiesProvider { if (config != null) { return config.getString(key); } else { - return extendedModel.getString(key.getKey()); + String result = extendedModel.getString(key.getKey()); + return result != null ? result : key.getDefaultValue(); } } -- cgit v1.2.3 From 3ae99730940f0f108a0c655f0cb52c109ca57885 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 6 Sep 2022 19:00:45 -0700 Subject: Handle Firebase error responses --- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 6510963c7..3723a4226 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -84,7 +84,12 @@ public class NotificatorFirebase implements Notificator { .build(); try { - FirebaseMessaging.getInstance().sendMulticast(message); + var result = FirebaseMessaging.getInstance().sendMulticast(message); + for (var response : result.getResponses()) { + if (!response.isSuccessful()) { + throw new MessageException(response.getException()); + } + } } catch (FirebaseMessagingException e) { throw new MessageException(e); } -- cgit v1.2.3 From 210e2cd641bf89d9b86d247a237739d026208bcf Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 4 Sep 2022 14:21:12 +0100 Subject: Added files for G1rus protocol --- .../java/org/traccar/protocol/G1rusProtocol.java | 24 ++++++++++++++++++++++ .../org/traccar/protocol/G1rusProtocolDecoder.java | 18 ++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/G1rusProtocol.java create mode 100644 src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocol.java b/src/main/java/org/traccar/protocol/G1rusProtocol.java new file mode 100644 index 000000000..0d77a8add --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusProtocol.java @@ -0,0 +1,24 @@ +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.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class G1rusProtocol extends BaseProtocol { + + @Inject + public G1rusProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new G1rusProtocolDecoder(G1rusProtocol.this)); + } + }); + } +} diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java new file mode 100644 index 000000000..f6251d6c2 --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; + +import java.net.SocketAddress; + +public class G1rusProtocolDecoder extends BaseProtocolDecoder { + public G1rusProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + } +} -- cgit v1.2.3 From 3899a7627ca99ce10f9f26a8f19477639510e298 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 10:35:17 +0100 Subject: Implemented basic REGULAR -> SYS -> GPS parsing --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 273 ++++++++++++++++++++- 1 file changed, 271 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index f6251d6c2..89303d1b1 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -1,18 +1,287 @@ package org.traccar.protocol; +import com.google.common.primitives.Doubles; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; +import org.traccar.session.DeviceSession; import java.net.SocketAddress; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; public class G1rusProtocolDecoder extends BaseProtocolDecoder { public G1rusProtocolDecoder(Protocol protocol) { super(protocol); } + private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); + + /* Constants */ + private static final int G1RUS_HEAD_TAIL = 0xF8; + + private static final int G1RUS_TYPE_HEARTBEAT = 0; + + private static final int G1RUS_TYPE_BCD_MASK = 0b00111111; + private static final int G1RUS_TYPE_REGULAR = 1; + private static final int G1RUS_TYPE_SMS_FORWARD = 2; + private static final int G1RUS_TYPE_SERIAL_PASS_THROUGH = 3; + private static final int G1RUS_TYPE_MIXED = 4; + + private static final int G1RUS_TYPE_EVENT_MASK = 0b01000000; + private static final int G1RUS_TYPE_NON_EVENT = 0; + private static final int G1RUS_TYPE_EVENT = 1; + + private static final int G1RUS_TYPE_IMEI_MASK = 0b10000000; + private static final int G1RUS_TYPE_IMEI_LONG = 0; + private static final int G1RUS_TYPE_IMEI_SHORT = 1; + + private static final int G1RUS_DATA_SYS_MASK = 0b00000001; + private static final int G1RUS_DATA_GPS_MASK = 0b00000010; + private static final int G1RUS_DATA_GSM_MASK = 0b00000100; + private static final int G1RUS_DATA_COT_MASK = 0b00001000; + private static final int G1RUS_DATA_ADC_MASK = 0b00010000; + private static final int G1RUS_DATA_DTT_MASK = 0b00100000; + /* Reserved */ + private static final int G1RUS_DATA_ETD_MASK = 0b10000000; + + private static final int G1RUS_GPS_SIGN_MASK = 0b00000001; + private static final int G1RUS_GPS_POS_MASK = 0b00000010; + private static final int G1RUS_GPS_SPD_MASK = 0b00000100; + private static final int G1RUS_GPS_AZTH_MASK = 0b00001000; + private static final int G1RUS_GPS_ALT_MASK = 0b00010000; + private static final int G1RUS_GPS_HDOP_MASK = 0b00100000; + private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; + private static final int G1RUS_GPS_STAT_MASK = 0b10000000; + + + private void decodeSYSSub(ByteBuf buf) { + LOGGER.info(""); + + buf.skipBytes(1); /* Total length */ + + /* NOTE: assuming order: + * Device name -> Firmware version -> Hardware version. + * TODO: actually check it. + */ + + /* Device name */ + byte devNameLen = (byte) buf.readUnsignedByte(); + byte[] devName = new byte[devNameLen & 0xF]; + buf.readBytes(devName); + String devNameString = new String(devName); + LOGGER.info("Device name: " + devNameString); + + /* Firmware version */ + byte firmwareLen = (byte) buf.readUnsignedByte(); + byte[] firmware = new byte[firmwareLen & 0xF]; + buf.readBytes(firmware); + String firmwareString = new String(firmware); + LOGGER.info("Firmware version: " + firmwareString); + + /* Hardware version */ + byte hardwareLen = (byte) buf.readUnsignedByte(); + byte[] hardware = new byte[hardwareLen & 0xF]; + buf.readBytes(hardware); + String hardwareString = new String(hardware); + LOGGER.info("Hardware version: " + hardwareString); + + LOGGER.info(""); + } + + + private void decodeGPSSub(ByteBuf buf, Position position) { + LOGGER.info(""); + + buf.skipBytes(1); /* Total length */ + + short subMask = (short) buf.readUnsignedShort(); + if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { + buf.skipBytes(1); + } + if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { + byte[] pos_buf = new byte[4]; + buf.readBytes(pos_buf); + position.setLatitude((float) Ints.fromByteArray(pos_buf) / 1000000); + LOGGER.info("Latitude: " + position.getLatitude()); + + buf.readBytes(pos_buf); + position.setLongitude((float) Ints.fromByteArray(pos_buf) / 1000000); + LOGGER.info("Longitude: " + position.getLongitude()); + } + if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { + position.setSpeed(buf.readUnsignedShort()); + LOGGER.info("Speed: " + position.getSpeed()); + } + if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { + position.setCourse(buf.readUnsignedShort()); + LOGGER.info("Course: " + position.getCourse()); + } + if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { + position.setAltitude(buf.readUnsignedShort()); + LOGGER.info("Altitude: " + position.getAltitude()); + } + if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { + buf.skipBytes(2); + } + if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { + buf.skipBytes(2); + } + + LOGGER.info(""); + } + + + private void decodeADCSub(ByteBuf buf, Position position) { + + } + + + private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, byte packetType) { + int timestamp_ = buf.readInt(); + long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ + LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); + + if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { + buf.skipBytes(1); /* Event ID */ + } + + DeviceSession deviceSession = null; + Position position = null; + + short dataUploadingMask = (short) buf.readUnsignedShort(); + if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { + decodeSYSSub(buf); + } + if ((dataUploadingMask & G1RUS_DATA_GPS_MASK) == G1RUS_DATA_GPS_MASK) { + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(imei)); + if (deviceSession == null) { + return null; + } + position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setTime(new Date(timestamp)); + + decodeGPSSub(buf, position); + } + if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { + /*if (deviceSession == null) { + return null; + }*/ + + buf.skipBytes(buf.readUnsignedByte()); + // decodeADCSub(buf, position); + } + if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + + return position; + } + + + private Object decodeSMSForward(ByteBuf buf) { + return null; + } + + + private Object decodeSerialPassThrough(ByteBuf buf) { + return null; + } + + + private void printPacketType(byte packetType) { + LOGGER.info("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : + "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + + "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + + "[" + ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR ? "REGULAR" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD ? "SMS FORWARD" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH ? "PASS THROUGH" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED ? "MIXED PACKED" : "RESERVED/INVALID") + "]")); + } + + @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(1); /* Head */ + + LOGGER.info("Protocol version: " + buf.readUnsignedByte()); + + byte packetType = (byte) buf.readUnsignedByte(); + printPacketType(packetType); + + byte[] imei = new byte[8]; + buf.readBytes(imei, 0, 7); + long imei_long = Longs.fromByteArray(imei); + LOGGER.info("IMEI: " + imei_long); + + List positions = null; + + if (packetType == G1RUS_TYPE_HEARTBEAT) { + return null; + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { + positions = new LinkedList<>(); + Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + if (position != null) { + positions.add(position); + } + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { + return decodeSMSForward(buf); + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { + return decodeSerialPassThrough(buf); + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED) { + positions = new LinkedList<>(); + + while (buf.readableBytes() > 3) { + short subPacketLength = (short) buf.readUnsignedShort(); + byte subPacketType = (byte) buf.readUnsignedByte(); + printPacketType(subPacketType); + + if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { + Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + if (position != null) { + positions.add(position); + } + } else { + try { + buf.skipBytes(subPacketLength - 1); + } catch (Exception e) { + return positions; + } + } + /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { + buf.skipBytes(subPacketLength - 1); + *//*decodeSMSForward(buf);*//* + } else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { + buf.skipBytes(subPacketLength - 1); + *//*decodeSerialPassThrough(buf);*//* + }*/ + } + } else { + LOGGER.error("Unknown packet type!"); + } + + buf.skipBytes(2); /* CRC */ /* TODO: actually check it */ + // buf.skipBytes(1); /* Tail */ + byte tail = (byte) buf.readUnsignedByte(); + + return positions; } } -- cgit v1.2.3 From 546f565023575c0975b7cc8fa3b9dea2f420918b Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 11:21:45 +0100 Subject: Added support for escaping byte sequences --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 107 +++++++++++++++------ 1 file changed, 75 insertions(+), 32 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 89303d1b1..d962e601e 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -3,6 +3,7 @@ package org.traccar.protocol; import com.google.common.primitives.Doubles; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; +import com.google.common.primitives.Shorts; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.slf4j.Logger; @@ -63,6 +64,50 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; private static final int G1RUS_GPS_STAT_MASK = 0b10000000; + private static final int G1RUS_ESCAPE_CHAR = 0x1B; + + + private byte readUnsignedByteUnescaped(ByteBuf buf) { + byte first = (byte) buf.readUnsignedByte(); + if (first != G1RUS_ESCAPE_CHAR) { + return first; + } else { /* first == 0x1B */ + byte second = (byte) buf.readUnsignedByte(); + if (second == 0x00) { + return first; + } else { /* second == 0xE3 */ + return (byte) 0xF8; + } + } + } + + + private void readBytesUnescaped(ByteBuf buf, byte[] to) { + for (int i = 0; i < to.length; ++i) { + to[i] = readUnsignedByteUnescaped(buf); + } + } + + private void readBytesUnescaped(ByteBuf buf, byte[] to, int dstIndex, int length) { + for (int i = dstIndex; i < length; ++i) { + to[i] = readUnsignedByteUnescaped(buf); + } + } + + + private short readUnsignedShortUnescaped(ByteBuf buf) { + byte[] shortBuf = new byte[2]; + readBytesUnescaped(buf, shortBuf); + return Shorts.fromByteArray(shortBuf); + } + + + private int readIntUnescaped(ByteBuf buf) { + byte[] intBuf = new byte[4]; + readBytesUnescaped(buf, intBuf); + return Ints.fromByteArray(intBuf); + } + private void decodeSYSSub(ByteBuf buf) { LOGGER.info(""); @@ -75,23 +120,23 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { */ /* Device name */ - byte devNameLen = (byte) buf.readUnsignedByte(); + byte devNameLen = readUnsignedByteUnescaped(buf); byte[] devName = new byte[devNameLen & 0xF]; - buf.readBytes(devName); + readBytesUnescaped(buf, devName); String devNameString = new String(devName); LOGGER.info("Device name: " + devNameString); /* Firmware version */ - byte firmwareLen = (byte) buf.readUnsignedByte(); + byte firmwareLen = readUnsignedByteUnescaped(buf); byte[] firmware = new byte[firmwareLen & 0xF]; - buf.readBytes(firmware); + readBytesUnescaped(buf, firmware); String firmwareString = new String(firmware); LOGGER.info("Firmware version: " + firmwareString); /* Hardware version */ - byte hardwareLen = (byte) buf.readUnsignedByte(); + byte hardwareLen = readUnsignedByteUnescaped(buf); byte[] hardware = new byte[hardwareLen & 0xF]; - buf.readBytes(hardware); + readBytesUnescaped(buf, hardware); String hardwareString = new String(hardware); LOGGER.info("Hardware version: " + hardwareString); @@ -104,30 +149,30 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(1); /* Total length */ - short subMask = (short) buf.readUnsignedShort(); + short subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { buf.skipBytes(1); } if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { byte[] pos_buf = new byte[4]; - buf.readBytes(pos_buf); + readBytesUnescaped(buf, pos_buf); position.setLatitude((float) Ints.fromByteArray(pos_buf) / 1000000); LOGGER.info("Latitude: " + position.getLatitude()); - buf.readBytes(pos_buf); + readBytesUnescaped(buf, pos_buf); position.setLongitude((float) Ints.fromByteArray(pos_buf) / 1000000); LOGGER.info("Longitude: " + position.getLongitude()); } if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { - position.setSpeed(buf.readUnsignedShort()); + position.setSpeed(readUnsignedShortUnescaped(buf)); LOGGER.info("Speed: " + position.getSpeed()); } if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { - position.setCourse(buf.readUnsignedShort()); + position.setCourse(readUnsignedShortUnescaped(buf)); LOGGER.info("Course: " + position.getCourse()); } if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { - position.setAltitude(buf.readUnsignedShort()); + position.setAltitude(readUnsignedShortUnescaped(buf)); LOGGER.info("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { @@ -147,7 +192,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, byte packetType) { - int timestamp_ = buf.readInt(); + int timestamp_ = readIntUnescaped(buf); long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); @@ -158,7 +203,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; Position position = null; - short dataUploadingMask = (short) buf.readUnsignedShort(); + short dataUploadingMask = readUnsignedShortUnescaped(buf); if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { decodeSYSSub(buf); } @@ -174,24 +219,24 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { decodeGPSSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { /*if (deviceSession == null) { return null; }*/ - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); // decodeADCSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } return position; @@ -220,15 +265,17 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; - buf.skipBytes(1); /* Head */ + if (buf.readUnsignedByte() != G1RUS_HEAD_TAIL) { + return null; + } - LOGGER.info("Protocol version: " + buf.readUnsignedByte()); + LOGGER.info("Protocol version: " + readUnsignedByteUnescaped(buf)); - byte packetType = (byte) buf.readUnsignedByte(); + byte packetType = readUnsignedByteUnescaped(buf); printPacketType(packetType); byte[] imei = new byte[8]; - buf.readBytes(imei, 0, 7); + readBytesUnescaped(buf, imei, 0, 7); long imei_long = Longs.fromByteArray(imei); LOGGER.info("IMEI: " + imei_long); @@ -249,22 +296,18 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED) { positions = new LinkedList<>(); - while (buf.readableBytes() > 3) { - short subPacketLength = (short) buf.readUnsignedShort(); - byte subPacketType = (byte) buf.readUnsignedByte(); + while (buf.readableBytes() > 5) { + short subPacketLength = readUnsignedShortUnescaped(buf); + byte subPacketType = readUnsignedByteUnescaped(buf); printPacketType(subPacketType); if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + Position position = decodeRegular(channel, remoteAddress, buf, imei_long, subPacketType); if (position != null) { positions.add(position); } } else { - try { - buf.skipBytes(subPacketLength - 1); - } catch (Exception e) { - return positions; - } + buf.skipBytes(subPacketLength - 1); } /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { buf.skipBytes(subPacketLength - 1); -- cgit v1.2.3 From 37976d783941a0ccf3a5a6bf9a24316515217629 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 11:50:52 +0100 Subject: Fixed skipping escaped bytes --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 70 +++++++++++++--------- 1 file changed, 41 insertions(+), 29 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index d962e601e..6d4ae9d1f 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -67,8 +67,8 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private static final int G1RUS_ESCAPE_CHAR = 0x1B; - private byte readUnsignedByteUnescaped(ByteBuf buf) { - byte first = (byte) buf.readUnsignedByte(); + private short readUnsignedByteUnescaped(ByteBuf buf) { + short first = buf.readUnsignedByte(); if (first != G1RUS_ESCAPE_CHAR) { return first; } else { /* first == 0x1B */ @@ -76,21 +76,28 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { if (second == 0x00) { return first; } else { /* second == 0xE3 */ - return (byte) 0xF8; + return (short) 0xF8; } } } + private void skipBytesUnescaped(ByteBuf buf, int howMany) { + for (int i = 0; i < howMany; ++i) { + readUnsignedByteUnescaped(buf); + } + } + + private void readBytesUnescaped(ByteBuf buf, byte[] to) { for (int i = 0; i < to.length; ++i) { - to[i] = readUnsignedByteUnescaped(buf); + to[i] = (byte) readUnsignedByteUnescaped(buf); } } private void readBytesUnescaped(ByteBuf buf, byte[] to, int dstIndex, int length) { for (int i = dstIndex; i < length; ++i) { - to[i] = readUnsignedByteUnescaped(buf); + to[i] = (byte) readUnsignedByteUnescaped(buf); } } @@ -112,7 +119,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeSYSSub(ByteBuf buf) { LOGGER.info(""); - buf.skipBytes(1); /* Total length */ + skipBytesUnescaped(buf, 1); /* Total length */ /* NOTE: assuming order: * Device name -> Firmware version -> Hardware version. @@ -120,21 +127,21 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { */ /* Device name */ - byte devNameLen = readUnsignedByteUnescaped(buf); + short devNameLen = readUnsignedByteUnescaped(buf); byte[] devName = new byte[devNameLen & 0xF]; readBytesUnescaped(buf, devName); String devNameString = new String(devName); LOGGER.info("Device name: " + devNameString); /* Firmware version */ - byte firmwareLen = readUnsignedByteUnescaped(buf); + short firmwareLen = readUnsignedByteUnescaped(buf); byte[] firmware = new byte[firmwareLen & 0xF]; readBytesUnescaped(buf, firmware); String firmwareString = new String(firmware); LOGGER.info("Firmware version: " + firmwareString); /* Hardware version */ - byte hardwareLen = readUnsignedByteUnescaped(buf); + short hardwareLen = readUnsignedByteUnescaped(buf); byte[] hardware = new byte[hardwareLen & 0xF]; readBytesUnescaped(buf, hardware); String hardwareString = new String(hardware); @@ -147,11 +154,11 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeGPSSub(ByteBuf buf, Position position) { LOGGER.info(""); - buf.skipBytes(1); /* Total length */ + skipBytesUnescaped(buf, 1); /* Total length */ short subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { - buf.skipBytes(1); + skipBytesUnescaped(buf, 1); } if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { byte[] pos_buf = new byte[4]; @@ -176,10 +183,10 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.info("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { - buf.skipBytes(2); + skipBytesUnescaped(buf, 2); } if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { - buf.skipBytes(2); + skipBytesUnescaped(buf, 2); } LOGGER.info(""); @@ -191,13 +198,13 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } - private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, byte packetType) { + private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, short packetType) { int timestamp_ = readIntUnescaped(buf); long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { - buf.skipBytes(1); /* Event ID */ + skipBytesUnescaped(buf, 1); /* Event ID */ } DeviceSession deviceSession = null; @@ -219,24 +226,24 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { decodeGPSSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { /*if (deviceSession == null) { return null; }*/ - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); // decodeADCSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } return position; @@ -253,7 +260,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } - private void printPacketType(byte packetType) { + private void printPacketType(short packetType) { LOGGER.info("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + @@ -271,7 +278,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.info("Protocol version: " + readUnsignedByteUnescaped(buf)); - byte packetType = readUnsignedByteUnescaped(buf); + short packetType = readUnsignedByteUnescaped(buf); printPacketType(packetType); byte[] imei = new byte[8]; @@ -298,7 +305,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { while (buf.readableBytes() > 5) { short subPacketLength = readUnsignedShortUnescaped(buf); - byte subPacketType = readUnsignedByteUnescaped(buf); + short subPacketType = readUnsignedByteUnescaped(buf); printPacketType(subPacketType); if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { @@ -307,13 +314,13 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } } else { - buf.skipBytes(subPacketLength - 1); + skipBytesUnescaped(buf, subPacketLength - 1); } /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { - buf.skipBytes(subPacketLength - 1); + skipBytesUnescaped(buf, subPacketLength - 1); *//*decodeSMSForward(buf);*//* } else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { - buf.skipBytes(subPacketLength - 1); + skipBytesUnescaped(buf, subPacketLength - 1); *//*decodeSerialPassThrough(buf);*//* }*/ } @@ -321,9 +328,14 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.error("Unknown packet type!"); } - buf.skipBytes(2); /* CRC */ /* TODO: actually check it */ - // buf.skipBytes(1); /* Tail */ - byte tail = (byte) buf.readUnsignedByte(); + skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ + // skipBytesUnescaped(buf, 1); /* Tail */ + short tail = buf.readUnsignedByte(); + if (tail == G1RUS_HEAD_TAIL) { + LOGGER.info("Tail: OK"); + } else { + LOGGER.error("Tail: FAIL!"); + } return positions; } -- cgit v1.2.3 From 24cb3a2faaa1fba33983e4e942af8d0c35df5802 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 12:19:23 +0100 Subject: Removed extra lines --- src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 6d4ae9d1f..056fc2d4d 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -1,6 +1,5 @@ package org.traccar.protocol; -import com.google.common.primitives.Doubles; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; @@ -329,7 +328,6 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ - // skipBytesUnescaped(buf, 1); /* Tail */ short tail = buf.readUnsignedByte(); if (tail == G1RUS_HEAD_TAIL) { LOGGER.info("Tail: OK"); -- cgit v1.2.3 From 6196ea366cfc5c668ef35940bcac50672badd82d Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 12:56:16 +0100 Subject: Added decoding of ADC sub-packet --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 49 +++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 056fc2d4d..24bd69d45 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -63,6 +63,8 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; private static final int G1RUS_GPS_STAT_MASK = 0b10000000; + private static final int G1RUS_ADC_DATA_MASK = 0b0000111111111111; + private static final int G1RUS_ESCAPE_CHAR = 0x1B; @@ -101,7 +103,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } - private short readUnsignedShortUnescaped(ByteBuf buf) { + private int readUnsignedShortUnescaped(ByteBuf buf) { byte[] shortBuf = new byte[2]; readBytesUnescaped(buf, shortBuf); return Shorts.fromByteArray(shortBuf); @@ -155,7 +157,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { skipBytesUnescaped(buf, 1); /* Total length */ - short subMask = readUnsignedShortUnescaped(buf); + int subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { skipBytesUnescaped(buf, 1); } @@ -192,8 +194,36 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } + private int getADValue(int rawValue) { + final int AD_MIN = -10; + final int AD_MAX = 100; + + return rawValue * (AD_MAX - AD_MIN) / 4096 + AD_MIN; + } + + private void decodeADCSub(ByteBuf buf, Position position) { + LOGGER.info(""); + + skipBytesUnescaped(buf, 1); + + /* NOTE: assuming order: + * External battery voltage -> Backup battery voltage -> Device temperature voltage. + * TODO: actually check this. + */ + int externalVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; + LOGGER.info("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); + + int backupVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; + LOGGER.info("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); + position.set(Position.KEY_BATTERY, getADValue(backupVoltage)); + + int temperature = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; + LOGGER.info("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); + position.set(Position.KEY_DEVICE_TEMP, getADValue(temperature)); + + LOGGER.info(""); } @@ -209,7 +239,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; Position position = null; - short dataUploadingMask = readUnsignedShortUnescaped(buf); + int dataUploadingMask = readUnsignedShortUnescaped(buf); if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { decodeSYSSub(buf); } @@ -231,12 +261,11 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { - /*if (deviceSession == null) { - return null; - }*/ - - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - // decodeADCSub(buf, position); + if (deviceSession == null) { + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); + } else { + decodeADCSub(buf, position); + } } if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); @@ -303,7 +332,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { positions = new LinkedList<>(); while (buf.readableBytes() > 5) { - short subPacketLength = readUnsignedShortUnescaped(buf); + int subPacketLength = readUnsignedShortUnescaped(buf); short subPacketType = readUnsignedByteUnescaped(buf); printPacketType(subPacketType); -- cgit v1.2.3 From 5dd61da7a9927bb28c880a5fe50997170aaf536c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 13:06:49 +0100 Subject: Added support for decoding more data from GPS sub-packet --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 24bd69d45..fd30b170e 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -159,16 +159,20 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { int subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { - skipBytesUnescaped(buf, 1); + short signValid = readUnsignedByteUnescaped(buf); + LOGGER.info("Fix sign: " + ((signValid & 0b1100000) >> 5)); + LOGGER.info("Satellite number: " + (signValid & 0b0011111)); + position.setValid(((signValid & 0b1100000) >> 5) == 2); + position.set(Position.KEY_SATELLITES, signValid & 0b0011111); } if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { - byte[] pos_buf = new byte[4]; - readBytesUnescaped(buf, pos_buf); - position.setLatitude((float) Ints.fromByteArray(pos_buf) / 1000000); + byte[] posBuf = new byte[4]; + readBytesUnescaped(buf, posBuf); + position.setLatitude((float) Ints.fromByteArray(posBuf) / 1000000); LOGGER.info("Latitude: " + position.getLatitude()); - readBytesUnescaped(buf, pos_buf); - position.setLongitude((float) Ints.fromByteArray(pos_buf) / 1000000); + readBytesUnescaped(buf, posBuf); + position.setLongitude((float) Ints.fromByteArray(posBuf) / 1000000); LOGGER.info("Longitude: " + position.getLongitude()); } if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { @@ -184,10 +188,12 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.info("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { - skipBytesUnescaped(buf, 2); + position.set(Position.KEY_HDOP, readUnsignedShortUnescaped(buf)); + LOGGER.info("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); } if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { - skipBytesUnescaped(buf, 2); + position.set(Position.KEY_VDOP, readUnsignedShortUnescaped(buf)); + LOGGER.info("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); } LOGGER.info(""); @@ -311,8 +317,8 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] imei = new byte[8]; readBytesUnescaped(buf, imei, 0, 7); - long imei_long = Longs.fromByteArray(imei); - LOGGER.info("IMEI: " + imei_long); + long imeiLong = Longs.fromByteArray(imei); + LOGGER.info("IMEI: " + imeiLong); List positions = null; @@ -320,7 +326,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { return null; } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { positions = new LinkedList<>(); - Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, packetType); if (position != null) { positions.add(position); } @@ -337,7 +343,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { printPacketType(subPacketType); if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - Position position = decodeRegular(channel, remoteAddress, buf, imei_long, subPacketType); + Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, subPacketType); if (position != null) { positions.add(position); } -- cgit v1.2.3 From d55ae464806430ee57bbd56737f024ead95748a2 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Wed, 7 Sep 2022 09:48:29 +0100 Subject: Moved logger messages to debug logs --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index fd30b170e..b1b7230e1 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -118,7 +118,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeSYSSub(ByteBuf buf) { - LOGGER.info(""); + LOGGER.debug(""); skipBytesUnescaped(buf, 1); /* Total length */ @@ -132,36 +132,36 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] devName = new byte[devNameLen & 0xF]; readBytesUnescaped(buf, devName); String devNameString = new String(devName); - LOGGER.info("Device name: " + devNameString); + LOGGER.debug("Device name: " + devNameString); /* Firmware version */ short firmwareLen = readUnsignedByteUnescaped(buf); byte[] firmware = new byte[firmwareLen & 0xF]; readBytesUnescaped(buf, firmware); String firmwareString = new String(firmware); - LOGGER.info("Firmware version: " + firmwareString); + LOGGER.debug("Firmware version: " + firmwareString); /* Hardware version */ short hardwareLen = readUnsignedByteUnescaped(buf); byte[] hardware = new byte[hardwareLen & 0xF]; readBytesUnescaped(buf, hardware); String hardwareString = new String(hardware); - LOGGER.info("Hardware version: " + hardwareString); + LOGGER.debug("Hardware version: " + hardwareString); - LOGGER.info(""); + LOGGER.debug(""); } private void decodeGPSSub(ByteBuf buf, Position position) { - LOGGER.info(""); + LOGGER.debug(""); skipBytesUnescaped(buf, 1); /* Total length */ int subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { short signValid = readUnsignedByteUnescaped(buf); - LOGGER.info("Fix sign: " + ((signValid & 0b1100000) >> 5)); - LOGGER.info("Satellite number: " + (signValid & 0b0011111)); + LOGGER.debug("Fix sign: " + ((signValid & 0b1100000) >> 5)); + LOGGER.debug("Satellite number: " + (signValid & 0b0011111)); position.setValid(((signValid & 0b1100000) >> 5) == 2); position.set(Position.KEY_SATELLITES, signValid & 0b0011111); } @@ -169,34 +169,34 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] posBuf = new byte[4]; readBytesUnescaped(buf, posBuf); position.setLatitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.info("Latitude: " + position.getLatitude()); + LOGGER.debug("Latitude: " + position.getLatitude()); readBytesUnescaped(buf, posBuf); position.setLongitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.info("Longitude: " + position.getLongitude()); + LOGGER.debug("Longitude: " + position.getLongitude()); } if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { position.setSpeed(readUnsignedShortUnescaped(buf)); - LOGGER.info("Speed: " + position.getSpeed()); + LOGGER.debug("Speed: " + position.getSpeed()); } if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { position.setCourse(readUnsignedShortUnescaped(buf)); - LOGGER.info("Course: " + position.getCourse()); + LOGGER.debug("Course: " + position.getCourse()); } if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { position.setAltitude(readUnsignedShortUnescaped(buf)); - LOGGER.info("Altitude: " + position.getAltitude()); + LOGGER.debug("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { position.set(Position.KEY_HDOP, readUnsignedShortUnescaped(buf)); - LOGGER.info("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); + LOGGER.debug("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); } if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { position.set(Position.KEY_VDOP, readUnsignedShortUnescaped(buf)); - LOGGER.info("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); + LOGGER.debug("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); } - LOGGER.info(""); + LOGGER.debug(""); } @@ -209,7 +209,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeADCSub(ByteBuf buf, Position position) { - LOGGER.info(""); + LOGGER.debug(""); skipBytesUnescaped(buf, 1); @@ -219,24 +219,24 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { */ int externalVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.info("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); + LOGGER.debug("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); int backupVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.info("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); + LOGGER.debug("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); position.set(Position.KEY_BATTERY, getADValue(backupVoltage)); int temperature = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.info("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); + LOGGER.debug("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); position.set(Position.KEY_DEVICE_TEMP, getADValue(temperature)); - LOGGER.info(""); + LOGGER.debug(""); } private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, short packetType) { int timestamp_ = readIntUnescaped(buf); long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ - LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); + LOGGER.debug("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { skipBytesUnescaped(buf, 1); /* Event ID */ @@ -295,7 +295,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void printPacketType(short packetType) { - LOGGER.info("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : + LOGGER.debug("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + "[" + ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR ? "REGULAR" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD ? "SMS FORWARD" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH ? "PASS THROUGH" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED ? "MIXED PACKED" : "RESERVED/INVALID") + "]")); @@ -310,7 +310,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { return null; } - LOGGER.info("Protocol version: " + readUnsignedByteUnescaped(buf)); + LOGGER.debug("Protocol version: " + readUnsignedByteUnescaped(buf)); short packetType = readUnsignedByteUnescaped(buf); printPacketType(packetType); @@ -318,7 +318,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] imei = new byte[8]; readBytesUnescaped(buf, imei, 0, 7); long imeiLong = Longs.fromByteArray(imei); - LOGGER.info("IMEI: " + imeiLong); + LOGGER.debug("IMEI: " + imeiLong); List positions = null; @@ -365,7 +365,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ short tail = buf.readUnsignedByte(); if (tail == G1RUS_HEAD_TAIL) { - LOGGER.info("Tail: OK"); + LOGGER.debug("Tail: OK"); } else { LOGGER.error("Tail: FAIL!"); } -- cgit v1.2.3 From 1359371f83393e4a6a5dcbc0df03ab1b33bebde5 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 17:32:01 +0100 Subject: Added high-level payload parsing --- .../traccar/protocol/PiligrimProtocolDecoder.java | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 244df6806..dca8b1329 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -30,6 +30,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -150,6 +151,33 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } return positions; + } else if (uri.startsWith("/push.do")) { + /* Getting payload */ + ByteBuf content_stream = request.content(); + byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; + content_stream.readBytes(payload_bytes); + String payload = new String(payload_bytes); + + /* Payload structure: + * &phone&message + */ + String[] payload_parts = payload.split("&"); + System.out.println("Payload parts: " + Arrays.toString(payload_parts)); + String phone_number = payload_parts[1].substring(12); + String message = payload_parts[2].substring(8); + System.out.println("Phone number: " + phone_number); + System.out.println("Message: " + message); + + /* Supported message structure: + * GPS NMEA Command; GSM info; Unknown; Battery voltage? + */ + if (message.startsWith("$GPRMC")) { + System.out.println("Supported message"); + } else { + System.out.println("Unsupported message"); + } + + System.out.println("Finish"); } return null; -- cgit v1.2.3 From 16197c4bec4da40372da7505c6b2093da6b743f5 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 17:47:13 +0100 Subject: Added high-level parsing of message field --- .../traccar/protocol/PiligrimProtocolDecoder.java | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index dca8b1329..29b6d9ef0 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -168,11 +168,28 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { System.out.println("Phone number: " + phone_number); System.out.println("Message: " + message); - /* Supported message structure: - * GPS NMEA Command; GSM info; Unknown; Battery voltage? - */ if (message.startsWith("$GPRMC")) { + /* Supported message structure: + * GPS NMEA Command; GSM info; Unknown; Battery voltage? + * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M + */ System.out.println("Supported message"); + + String[] message_parts = message.split(";"); + System.out.println("Message parts: " + Arrays.toString(message_parts)); + + /* Parsing GPS */ + String unprocessed_gps_command = message_parts[0]; + + /* Getting rid of checksum */ + String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); + System.out.println("GPS command: " + gps_command); + + /* Parsing other fields */ + /* String gsm_info = message_parts[1]; */ + /* String unknown = message_parts[2]; */ + String battery_info = message_parts[3].substring(7).substring(0, 3); + System.out.println("Battery: " + battery_info); } else { System.out.println("Unsupported message"); } -- cgit v1.2.3 From 3ead0772172daeb3d6fedab5f04a32c33b9d5ebb Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 17:53:21 +0100 Subject: Added NMEA parser (that doesn't s**ck) --- src/main/java/org/traccar/helper/NMEA.java | 126 +++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/main/java/org/traccar/helper/NMEA.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/NMEA.java b/src/main/java/org/traccar/helper/NMEA.java new file mode 100644 index 000000000..cae47a8f6 --- /dev/null +++ b/src/main/java/org/traccar/helper/NMEA.java @@ -0,0 +1,126 @@ +package org.traccar.helper; + +import java.util.HashMap; +import java.util.Map; + + +public class NMEA { + + // fucking java interfaces + interface SentenceParser { + public boolean parse(String[] tokens, GPSPosition position); + } + + // utils + static float Latitude2Decimal(String lat, String NS) { + float med = Float.parseFloat(lat.substring(2)) / 60.0f; + med += Float.parseFloat(lat.substring(0, 2)); + if (NS.startsWith("S")) { + med = -med; + } + return med; + } + + static float Longitude2Decimal(String lon, String WE) { + float med = Float.parseFloat(lon.substring(3)) / 60.0f; + med += Float.parseFloat(lon.substring(0, 3)); + if (WE.startsWith("W")) { + med = -med; + } + return med; + } + + // parsers + class GPGGA implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.time = Float.parseFloat(tokens[1]); + position.lat = Latitude2Decimal(tokens[2], tokens[3]); + position.lon = Longitude2Decimal(tokens[4], tokens[5]); + position.quality = Integer.parseInt(tokens[6]); + position.altitude = Float.parseFloat(tokens[9]); + return true; + } + } + + class GPGGL implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.lat = Latitude2Decimal(tokens[1], tokens[2]); + position.lon = Longitude2Decimal(tokens[3], tokens[4]); + position.time = Float.parseFloat(tokens[5]); + return true; + } + } + + class GPRMC implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.time = Float.parseFloat(tokens[1]); + position.lat = Latitude2Decimal(tokens[3], tokens[4]); + position.lon = Longitude2Decimal(tokens[5], tokens[6]); + position.velocity = Float.parseFloat(tokens[7]); + position.dir = Float.parseFloat(tokens[8]); + return true; + } + } + + class GPVTG implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.dir = Float.parseFloat(tokens[3]); + return true; + } + } + + class GPRMZ implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.altitude = Float.parseFloat(tokens[1]); + return true; + } + } + + public class GPSPosition { + public float time = 0.0f; + public float lat = 0.0f; + public float lon = 0.0f; + public boolean fixed = false; + public int quality = 0; + public float dir = 0.0f; + public float altitude = 0.0f; + public float velocity = 0.0f; + + public void updatefix() { + fixed = quality > 0; + } + + public String toString() { + return String.format("POSITION: lat: %f, lon: %f, time: %f, Q: %d, dir: %f, alt: %f, vel: %f", lat, lon, time, quality, dir, altitude, velocity); + } + } + + GPSPosition position = new GPSPosition(); + + private static final Map sentenceParsers = new HashMap(); + + public NMEA() { + sentenceParsers.put("GPGGA", new GPGGA()); + sentenceParsers.put("GPGGL", new GPGGL()); + sentenceParsers.put("GPRMC", new GPRMC()); + sentenceParsers.put("GPRMZ", new GPRMZ()); + //only really good GPS devices have this sentence but ... + sentenceParsers.put("GPVTG", new GPVTG()); + } + + public GPSPosition parse(String line) { + + if (line.startsWith("$")) { + String nmea = line.substring(1); + String[] tokens = nmea.split(","); + String type = tokens[0]; + //TODO check crc + if (sentenceParsers.containsKey(type)) { + sentenceParsers.get(type).parse(tokens, position); + } + position.updatefix(); + } + + return position; + } +} -- cgit v1.2.3 From 2274b42c6b1c7b1ef90e3ec4e5e956afe66eaa6d Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 18:01:41 +0100 Subject: Added parsing of GPS NMEA message --- .../java/org/traccar/protocol/PiligrimProtocolDecoder.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 29b6d9ef0..7f9d20822 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -26,6 +26,7 @@ import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; +import org.traccar.helper.NMEA; import org.traccar.model.Position; import java.net.SocketAddress; @@ -163,7 +164,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { */ String[] payload_parts = payload.split("&"); System.out.println("Payload parts: " + Arrays.toString(payload_parts)); - String phone_number = payload_parts[1].substring(12); + String phone_number = payload_parts[1].substring(15); String message = payload_parts[2].substring(8); System.out.println("Phone number: " + phone_number); System.out.println("Message: " + message); @@ -185,6 +186,14 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); System.out.println("GPS command: " + gps_command); + NMEA gps_parser = new NMEA(); + + NMEA.GPSPosition gps_position = gps_parser.parse(gps_command); + + System.out.println("Time: " + gps_position.time); + System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); + System.out.println("Speed over ground: " + gps_position.velocity + " knots"); + /* Parsing other fields */ /* String gsm_info = message_parts[1]; */ /* String unknown = message_parts[2]; */ -- cgit v1.2.3 From 62b38f2ccf0db60e7e953485898a1d3bf5c452e0 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 18:36:33 +0100 Subject: WIP: Added position return --- .../traccar/protocol/PiligrimProtocolDecoder.java | 28 ++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 7f9d20822..967adb82b 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -21,6 +21,7 @@ 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 net.fortuna.ical4j.model.DateTime; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.session.DeviceSession; import org.traccar.Protocol; @@ -32,6 +33,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -153,6 +155,13 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { return positions; } else if (uri.startsWith("/push.do")) { + sendResponse(channel, "PUSH.DO: OK"); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, "123456"); + if (deviceSession == null) { + return null; + } + /* Getting payload */ ByteBuf content_stream = request.content(); byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; @@ -199,11 +208,26 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* String unknown = message_parts[2]; */ String battery_info = message_parts[3].substring(7).substring(0, 3); System.out.println("Battery: " + battery_info); + + /* Constructing response */ + Position position = new Position(getProtocolName()); + + position.setDeviceId(deviceSession.getDeviceId()); + position.setValid(true); + position.setLatitude(gps_position.lat); + position.setLongitude(gps_position.lon); + position.setTime(new Date(System.currentTimeMillis())); + position.setSpeed(gps_position.velocity); + position.setCourse(gps_position.dir); + position.setAccuracy(gps_position.quality); + position.set(Position.KEY_BATTERY, Integer.parseInt(battery_info) / 100); + + System.out.println("Supported message finish"); + + return position; } else { System.out.println("Unsupported message"); } - - System.out.println("Finish"); } return null; -- cgit v1.2.3 From b66d4c3b3250edac4762176277f4f07bc2e74d8e Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 18:43:30 +0100 Subject: Commented out 'System.out.println()'s --- .../org/traccar/protocol/PiligrimProtocolDecoder.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 967adb82b..775032b64 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -172,11 +172,11 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { * &phone&message */ String[] payload_parts = payload.split("&"); - System.out.println("Payload parts: " + Arrays.toString(payload_parts)); + /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ String phone_number = payload_parts[1].substring(15); String message = payload_parts[2].substring(8); - System.out.println("Phone number: " + phone_number); - System.out.println("Message: " + message); + /* System.out.println("Phone number: " + phone_number); */ + /* System.out.println("Message: " + message); */ if (message.startsWith("$GPRMC")) { /* Supported message structure: @@ -186,28 +186,28 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { System.out.println("Supported message"); String[] message_parts = message.split(";"); - System.out.println("Message parts: " + Arrays.toString(message_parts)); + /* System.out.println("Message parts: " + Arrays.toString(message_parts)); */ /* Parsing GPS */ String unprocessed_gps_command = message_parts[0]; /* Getting rid of checksum */ String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); - System.out.println("GPS command: " + gps_command); + /* System.out.println("GPS command: " + gps_command); */ NMEA gps_parser = new NMEA(); NMEA.GPSPosition gps_position = gps_parser.parse(gps_command); - System.out.println("Time: " + gps_position.time); - System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); - System.out.println("Speed over ground: " + gps_position.velocity + " knots"); + /* System.out.println("Time: " + gps_position.time); */ + /* System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); */ + /* System.out.println("Speed over ground: " + gps_position.velocity + " knots"); */ /* Parsing other fields */ /* String gsm_info = message_parts[1]; */ /* String unknown = message_parts[2]; */ String battery_info = message_parts[3].substring(7).substring(0, 3); - System.out.println("Battery: " + battery_info); + /* System.out.println("Battery: " + battery_info); */ /* Constructing response */ Position position = new Position(getProtocolName()); -- cgit v1.2.3 From 26e3d616ef17db2c30da0e9c8c0a7a1e9182cc6c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 19:18:49 +0100 Subject: Added workaround for 'ALARM KEY;' --- src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 775032b64..d1f667f6f 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -173,8 +173,8 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { */ String[] payload_parts = payload.split("&"); /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ - String phone_number = payload_parts[1].substring(15); - String message = payload_parts[2].substring(8); + /* String phone_number = payload_parts[1].substring(15); */ + String message = payload_parts[2].substring(8).replaceFirst("ALARM KEY; ", ""); /* System.out.println("Phone number: " + phone_number); */ /* System.out.println("Message: " + message); */ @@ -220,6 +220,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { position.setSpeed(gps_position.velocity); position.setCourse(gps_position.dir); position.setAccuracy(gps_position.quality); + position.setAltitude(gps_position.altitude); position.set(Position.KEY_BATTERY, Integer.parseInt(battery_info) / 100); System.out.println("Supported message finish"); -- cgit v1.2.3 From b3caf3c1cee6cb665e8ac05be35d9258c353771e Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 10:53:38 +0100 Subject: Replaced hard-coded ID with phone number --- .../org/traccar/protocol/PiligrimProtocolDecoder.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index d1f667f6f..da8991bd3 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -157,11 +157,6 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } else if (uri.startsWith("/push.do")) { sendResponse(channel, "PUSH.DO: OK"); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, "123456"); - if (deviceSession == null) { - return null; - } - /* Getting payload */ ByteBuf content_stream = request.content(); byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; @@ -173,7 +168,15 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { */ String[] payload_parts = payload.split("&"); /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ - /* String phone_number = payload_parts[1].substring(15); */ + String phone_number = payload_parts[1].substring(15); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phone_number); + if (deviceSession == null) { + return null; + } + + /* TODO: generalize this process; + * TODO: use keys for flags in 'positions'. + */ String message = payload_parts[2].substring(8).replaceFirst("ALARM KEY; ", ""); /* System.out.println("Phone number: " + phone_number); */ /* System.out.println("Message: " + message); */ -- cgit v1.2.3 From bd49d52fc47dcb902b9fb2b3e8cf82d9550a025c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 10:58:20 +0100 Subject: Refactored naming convention to 'camelCase' and changed 'System.out.println' to 'LOGGER.info' --- .../traccar/protocol/PiligrimProtocolDecoder.java | 77 +++++++++++----------- 1 file changed, 40 insertions(+), 37 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index da8991bd3..0a22e30c5 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -21,8 +21,10 @@ 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 net.fortuna.ical4j.model.DateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.WebDataHandler; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -32,13 +34,14 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; -import java.util.Arrays; import java.util.Date; import java.util.LinkedList; import java.util.List; public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { + private static final Logger LOGGER = LoggerFactory.getLogger(WebDataHandler.class); + public PiligrimProtocolDecoder(Protocol protocol) { super(protocol); } @@ -158,18 +161,18 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { sendResponse(channel, "PUSH.DO: OK"); /* Getting payload */ - ByteBuf content_stream = request.content(); - byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; - content_stream.readBytes(payload_bytes); - String payload = new String(payload_bytes); + ByteBuf contentStream = request.content(); + byte[] payloadBytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; + contentStream.readBytes(payloadBytes); + String payload = new String(payloadBytes); /* Payload structure: * &phone&message */ - String[] payload_parts = payload.split("&"); - /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ - String phone_number = payload_parts[1].substring(15); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phone_number); + String[] payloadParts = payload.split("&"); + /* LOGGER.info("Payload parts: " + Arrays.toString(payloadParts)); */ + String phoneNumber = payloadParts[1].substring(15); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber); if (deviceSession == null) { return null; } @@ -177,60 +180,60 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* TODO: generalize this process; * TODO: use keys for flags in 'positions'. */ - String message = payload_parts[2].substring(8).replaceFirst("ALARM KEY; ", ""); - /* System.out.println("Phone number: " + phone_number); */ - /* System.out.println("Message: " + message); */ + String message = payloadParts[2].substring(8).replaceFirst("ALARM KEY; ", ""); + /* LOGGER.info("Phone number: " + phoneNumber); */ + /* LOGGER.info("Message: " + message); */ if (message.startsWith("$GPRMC")) { /* Supported message structure: * GPS NMEA Command; GSM info; Unknown; Battery voltage? * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M */ - System.out.println("Supported message"); + LOGGER.info("Supported message"); - String[] message_parts = message.split(";"); - /* System.out.println("Message parts: " + Arrays.toString(message_parts)); */ + String[] messageParts = message.split(";"); + /* LOGGER.info("Message parts: " + Arrays.toString(messageParts)); */ /* Parsing GPS */ - String unprocessed_gps_command = message_parts[0]; + String unprocessedGpsCommand = messageParts[0]; /* Getting rid of checksum */ - String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); - /* System.out.println("GPS command: " + gps_command); */ + String gpsCommand = unprocessedGpsCommand.replaceFirst("A,V[*].*", ""); + /* LOGGER.info("GPS command: " + gpsCommand); */ - NMEA gps_parser = new NMEA(); + NMEA gpsParser = new NMEA(); - NMEA.GPSPosition gps_position = gps_parser.parse(gps_command); + NMEA.GPSPosition gpsPosition = gpsParser.parse(gpsCommand); - /* System.out.println("Time: " + gps_position.time); */ - /* System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); */ - /* System.out.println("Speed over ground: " + gps_position.velocity + " knots"); */ + /* LOGGER.info("Time: " + gpsPosition.time); */ + /* LOGGER.info("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ + /* LOGGER.info("Speed over ground: " + gpsPosition.velocity + " knots"); */ /* Parsing other fields */ - /* String gsm_info = message_parts[1]; */ - /* String unknown = message_parts[2]; */ - String battery_info = message_parts[3].substring(7).substring(0, 3); - /* System.out.println("Battery: " + battery_info); */ + /* String gsmInfo = messageParts[1]; */ + /* String unknown = messageParts[2]; */ + String batteryInfo = messageParts[3].substring(7).substring(0, 3); + /* LOGGER.info("Battery: " + batteryInfo); */ /* Constructing response */ Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.setValid(true); - position.setLatitude(gps_position.lat); - position.setLongitude(gps_position.lon); + position.setLatitude(gpsPosition.lat); + position.setLongitude(gpsPosition.lon); position.setTime(new Date(System.currentTimeMillis())); - position.setSpeed(gps_position.velocity); - position.setCourse(gps_position.dir); - position.setAccuracy(gps_position.quality); - position.setAltitude(gps_position.altitude); - position.set(Position.KEY_BATTERY, Integer.parseInt(battery_info) / 100); + position.setSpeed(gpsPosition.velocity); + position.setCourse(gpsPosition.dir); + position.setAccuracy(gpsPosition.quality); + position.setAltitude(gpsPosition.altitude); + position.set(Position.KEY_BATTERY, Integer.parseInt(batteryInfo) / 100); - System.out.println("Supported message finish"); + LOGGER.info("Supported message finish"); return position; } else { - System.out.println("Unsupported message"); + LOGGER.info("Unsupported message"); } } -- cgit v1.2.3 From 55ac4060c38b2ea6e583cbef570f4b9ec35d8b15 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 11:18:57 +0100 Subject: Changed regex for replacing event keys --- src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 0a22e30c5..ca6b667cd 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -172,15 +172,13 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { String[] payloadParts = payload.split("&"); /* LOGGER.info("Payload parts: " + Arrays.toString(payloadParts)); */ String phoneNumber = payloadParts[1].substring(15); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber.substring(1)); if (deviceSession == null) { return null; } - /* TODO: generalize this process; - * TODO: use keys for flags in 'positions'. - */ - String message = payloadParts[2].substring(8).replaceFirst("ALARM KEY; ", ""); + /* TODO: use keys for flags in 'positions'. */ + String message = payloadParts[2].substring(8).replaceFirst("[A-Z]* KEY; ", ""); /* LOGGER.info("Phone number: " + phoneNumber); */ /* LOGGER.info("Message: " + message); */ -- cgit v1.2.3 From 278f8c934ec440a6472d467688bfa1c42078bbac Mon Sep 17 00:00:00 2001 From: anton2920 Date: Wed, 7 Sep 2022 09:46:48 +0100 Subject: Fixed regex for replacing event keys --- src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index ca6b667cd..6b3b35eee 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -178,7 +178,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } /* TODO: use keys for flags in 'positions'. */ - String message = payloadParts[2].substring(8).replaceFirst("[A-Z]* KEY; ", ""); + String message = payloadParts[2].substring(8).replaceFirst("[a-zA-Z! ]*; ", ""); /* LOGGER.info("Phone number: " + phoneNumber); */ /* LOGGER.info("Message: " + message); */ @@ -210,7 +210,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* Parsing other fields */ /* String gsmInfo = messageParts[1]; */ /* String unknown = messageParts[2]; */ - String batteryInfo = messageParts[3].substring(7).substring(0, 3); + String batteryInfo = messageParts[messageParts.length - 1].substring(7).substring(0, 3); /* LOGGER.info("Battery: " + batteryInfo); */ /* Constructing response */ @@ -231,7 +231,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { return position; } else { - LOGGER.info("Unsupported message"); + LOGGER.error("Unsupported message"); } } -- cgit v1.2.3 From e5c73ce4fcfc67f13a9151a130783b31cef76293 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Wed, 7 Sep 2022 09:47:47 +0100 Subject: Moved logger messages to debug logs --- .../traccar/protocol/PiligrimProtocolDecoder.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 6b3b35eee..6ca9b0795 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -170,7 +170,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { * &phone&message */ String[] payloadParts = payload.split("&"); - /* LOGGER.info("Payload parts: " + Arrays.toString(payloadParts)); */ + /* LOGGER.debug("Payload parts: " + Arrays.toString(payloadParts)); */ String phoneNumber = payloadParts[1].substring(15); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber.substring(1)); if (deviceSession == null) { @@ -179,39 +179,39 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* TODO: use keys for flags in 'positions'. */ String message = payloadParts[2].substring(8).replaceFirst("[a-zA-Z! ]*; ", ""); - /* LOGGER.info("Phone number: " + phoneNumber); */ - /* LOGGER.info("Message: " + message); */ + /* LOGGER.debug("Phone number: " + phoneNumber); */ + /* LOGGER.debug("Message: " + message); */ if (message.startsWith("$GPRMC")) { /* Supported message structure: * GPS NMEA Command; GSM info; Unknown; Battery voltage? * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M */ - LOGGER.info("Supported message"); + LOGGER.debug("Supported message"); String[] messageParts = message.split(";"); - /* LOGGER.info("Message parts: " + Arrays.toString(messageParts)); */ + /* LOGGER.debug("Message parts: " + Arrays.toString(messageParts)); */ /* Parsing GPS */ String unprocessedGpsCommand = messageParts[0]; /* Getting rid of checksum */ String gpsCommand = unprocessedGpsCommand.replaceFirst("A,V[*].*", ""); - /* LOGGER.info("GPS command: " + gpsCommand); */ + /* LOGGER.debug("GPS command: " + gpsCommand); */ NMEA gpsParser = new NMEA(); NMEA.GPSPosition gpsPosition = gpsParser.parse(gpsCommand); - /* LOGGER.info("Time: " + gpsPosition.time); */ - /* LOGGER.info("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ - /* LOGGER.info("Speed over ground: " + gpsPosition.velocity + " knots"); */ + /* LOGGER.debug("Time: " + gpsPosition.time); */ + /* LOGGER.debug("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ + /* LOGGER.debug("Speed over ground: " + gpsPosition.velocity + " knots"); */ /* Parsing other fields */ /* String gsmInfo = messageParts[1]; */ /* String unknown = messageParts[2]; */ String batteryInfo = messageParts[messageParts.length - 1].substring(7).substring(0, 3); - /* LOGGER.info("Battery: " + batteryInfo); */ + /* LOGGER.debug("Battery: " + batteryInfo); */ /* Constructing response */ Position position = new Position(getProtocolName()); @@ -227,7 +227,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { position.setAltitude(gpsPosition.altitude); position.set(Position.KEY_BATTERY, Integer.parseInt(batteryInfo) / 100); - LOGGER.info("Supported message finish"); + LOGGER.debug("Supported message finish"); return position; } else { -- 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 'src/main/java/org') 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 596f755e19ec38cf5ce426595e2fba1a5b156338 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Sep 2022 06:15:12 -0700 Subject: Attributes never null --- src/main/java/org/traccar/model/ExtendedModel.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 0fa1856d1..ef2e3b68f 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 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. @@ -17,6 +17,7 @@ package org.traccar.model; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; public class ExtendedModel extends BaseModel { @@ -31,7 +32,7 @@ public class ExtendedModel extends BaseModel { } public void setAttributes(Map attributes) { - this.attributes = attributes; + this.attributes = Objects.requireNonNullElseGet(attributes, LinkedHashMap::new); } public void set(String key, Boolean value) { -- 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 'src/main/java/org') 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 9b5654e253ed3dedfb43125a0611896dfa8fc863 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Sep 2022 08:03:04 -0700 Subject: Handle unlinked notifications --- src/main/java/org/traccar/session/cache/CacheManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 6f6b648fa..64397b368 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -132,7 +132,7 @@ public class CacheManager implements BroadcastInterface { lock.readLock().lock(); var users = deviceLinks.get(deviceId).get(User.class).stream() .collect(Collectors.toUnmodifiableSet()); - return notificationUsers.get(notificationId).stream() + return notificationUsers.getOrDefault(notificationId, new LinkedList<>()).stream() .filter(user -> users.contains(user.getId())) .collect(Collectors.toUnmodifiableList()); } finally { -- cgit v1.2.3 From ff95c7dc0adf17710438f7dd2168d6ad1dd31415 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 9 Sep 2022 16:59:54 -0700 Subject: Decode G18 light sensor --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 5 +++-- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index b65e4a4b8..885ea4bab 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -411,9 +411,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case 0x11: return Position.ALARM_POWER_OFF; case 0x13: + case 0x25: return Position.ALARM_TAMPERING; case 0x14: return Position.ALARM_DOOR; + case 0x23: + return Position.ALARM_FALL_DOWN; case 0x29: return Position.ALARM_ACCELERATION; case 0x30: @@ -423,8 +426,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_CORNERING; case 0x2C: return Position.ALARM_ACCIDENT; - case 0x23: - return Position.ALARM_FALL_DOWN; default: return null; } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index f3f47a104..6ab78260c 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78782516160908063736c0006e70110442fc800000000800000000000000000300002512000473fb0d0a"), + Position.KEY_ALARM, Position.ALARM_TAMPERING); + verifyPosition(decoder, binary( "78782e2416061a103600c80275298404a0a24000184602d4023a49006f060104ed01940000086508004139765000be7d640d0a")); -- cgit v1.2.3 From 725195a271f4313255b80c99278b3a91cff799e1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 9 Sep 2022 17:35:56 -0700 Subject: Add DT700 bluetooth temperature --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 10 ++++++++++ .../java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 14 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 5393c6f74..d2b8f1fb5 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -513,6 +513,16 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_MOTION, BitUtil.check(deviceStatus, 2)); position.set("cover", BitUtil.check(deviceStatus, 3)); break; + case 0xE6: + int sensorIndex = buf.readUnsignedByte(); + buf.skipBytes(6); // mac + position.set( + Position.PREFIX_TEMP + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set( + "humidity" + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + break; case 0xEB: if (buf.getUnsignedShort(buf.readerIndex()) > 200) { Network network = new Network(); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 7322185d5..4ef2e25ea 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "7e0200003d012291302256004800000000000c012300d2648805ff31db000e0000000022090708255503020000a70400000000ac04000002bce5020000e60b01dd34020754fe1bce3efc357e"), + Position.PREFIX_TEMP + 1, 29.06); + verifyAttribute(decoder, binary( "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), Position.KEY_ALARM, Position.ALARM_ACCELERATION); -- cgit v1.2.3 From 18807d840ce04f8052f4b1fc842f4ad2da958326 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Sep 2022 16:37:53 -0700 Subject: Fix GT800 door decoding --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 7 +++++++ src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 885ea4bab..7eeee5efb 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -987,6 +987,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (subType == 0x05) { + if (buf.readableBytes() >= 6 + 1 + 6) { + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + position.setDeviceTime(dateBuilder.getDate()); + } + int flags = buf.readUnsignedByte(); position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 6ab78260c..1570dcf32 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "7979000d940516090908081c030defbd2d0d0a"), + Position.KEY_DOOR, true); + verifyAttribute(decoder, binary( "78782516160908063736c0006e70110442fc800000000800000000000000000300002512000473fb0d0a"), Position.KEY_ALARM, Position.ALARM_TAMPERING); -- cgit v1.2.3 From 251829fb7583c50c0bac97bc47d41bdbf63cf6c1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Sep 2022 06:01:02 -0700 Subject: Fix manager permission check --- src/main/java/org/traccar/api/security/PermissionsService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index a494c0257..ddfaaab94 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -170,8 +170,10 @@ public class PermissionsService { || before.getFixedEmail() != after.getFixedEmail()) { if (userId == after.getId()) { checkAdmin(userId); - } else { + } else if (after.getId() > 0) { checkUser(userId, after.getId()); + } else { + checkManager(userId); } } if (before.getFixedEmail() && !before.getEmail().equals(after.getEmail())) { -- cgit v1.2.3 From 73407e12acce8061cc1aa3d18517569368707864 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Sep 2022 17:55:45 -0700 Subject: Safer Teltonika IO decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 5 ++++- src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 89124cb22..ff1f52eb1 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -325,6 +325,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { + int index = buf.readerIndex(); boolean decoded = false; for (var entry : PARAMETERS.getOrDefault(id, new HashMap<>()).entrySet()) { if (entry.getKey() == null || model != null && entry.getKey().contains(model)) { @@ -333,7 +334,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { break; } } - if (!decoded) { + if (decoded) { + buf.readerIndex(index + length); + } else { position.set(Position.PREFIX_IO + id, readValue(buf, length)); } } diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 994a55109..197391d7f 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000004258e0400000182a701b49301d5d90ab7ebe4aae101be003d12000000f7003d000e00f70100ef0000f00000500500150200c800004501000100001d00001400001600001700007157010701001d00b5000b00b60006004230400018000000cd223f00ce741700430f8900440000000d00010011ffe50012001f0013ffce000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333382e0100000053a6fb624588040001ba86064f0eae51c0fdaf4d3de500000182a701b82001d5d90ab7ebe4aae101be003d12000000f0003c000d00ef0000f00100500500150200c800004501000100001d00001400001600001700007152010701001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a701bc0801d5d90ab7ebe4aae101be003d12000000fc003d000e00ef0000f00100500500150200c800004501000100001d0000140000160000170000714d01070100fc01001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a7018d8d01d5d8ffa6ebe4a0ca01be006111000000f70001000100f70500000000000000000400003a10")); + verifyPositions(decoder, binary( "00000000000003831004000001735ace37f80000e3b9331c71e290006900e211005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005538006e00006f00007a03007d00007f5600890000fd0200fe1f09004326b00044000000b5000b00b6000600427029001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022a1005000000054005400000000005600015568005700000060005800000420006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ca80000e3b08a1c71dd29006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe1d09004326ac0044000000b5000b00b600060042701f001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022ce00500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3fc80000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ffa0000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0300fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000040000eb85")); -- cgit v1.2.3 From 729bf987349dc9230293140139dd8ad10b7de107 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Sep 2022 18:17:28 -0700 Subject: Handle multiple DT700 sensors --- .../org/traccar/protocol/HuabaoProtocolDecoder.java | 18 ++++++++++-------- .../traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index d2b8f1fb5..0639b9dcf 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -514,14 +514,16 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set("cover", BitUtil.check(deviceStatus, 3)); break; case 0xE6: - int sensorIndex = buf.readUnsignedByte(); - buf.skipBytes(6); // mac - position.set( - Position.PREFIX_TEMP + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); - position.set( - "humidity" + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + while (buf.readerIndex() < endIndex) { + int sensorIndex = buf.readUnsignedByte(); + buf.skipBytes(6); // mac + position.set( + Position.PREFIX_TEMP + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set( + "humidity" + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + } break; case 0xEB: if (buf.getUnsignedShort(buf.readerIndex()) > 200) { diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 4ef2e25ea..3661a0202 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -12,8 +12,8 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); verifyAttribute(decoder, binary( - "7e0200003d012291302256004800000000000c012300d2648805ff31db000e0000000022090708255503020000a70400000000ac04000002bce5020000e60b01dd34020754fe1bce3efc357e"), - Position.PREFIX_TEMP + 1, 29.06); + "7e0200005e01229130231209e300000000000c002300d264a305ff322300160000000022091514493503020000a70400000000ac0400000000e5020003e62c01bc5729009ca319bbff0002dd34020754fe1a83393c03bc572900ce371a6133d704dd34020751551d00fefb9a7e"), + Position.PREFIX_TEMP + 4, 29.0); verifyAttribute(decoder, binary( "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), -- cgit v1.2.3 From fd2e2183bb34951e5e9248b77e93b2e4abf1c94e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Sep 2022 18:29:28 -0700 Subject: Add Fifotrack Q2 response --- .../traccar/protocol/FifotrackProtocolDecoder.java | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 741f4b35a..a9d77b46e 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -34,6 +34,10 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; import java.util.regex.Pattern; public class FifotrackProtocolDecoder extends BaseProtocolDecoder { @@ -78,7 +82,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .text("$$") .number("d+,") // length .number("(d+),") // imei - .number("x+,") // index + .number("(x+),") // index .text("A03,") // type .number("(d+)?,") // alarm .number("(dd)(dd)(dd)") // date (yymmdd) @@ -137,16 +141,20 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .number("xx") .compile(); - private void requestPhoto(Channel channel, SocketAddress socketAddress, String imei, String file) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String imei, String content) { if (channel != null) { - String content = "1,D06," + file + "," + photo.writerIndex() + "," + Math.min(1024, photo.writableBytes()); int length = 1 + imei.length() + 1 + content.length(); String response = String.format("##%02d,%s,%s*", length, imei, content); response += Checksum.sum(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, socketAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } + private void requestPhoto(Channel channel, SocketAddress remoteAddress, String imei, String file) { + String content = "1,D06," + file + "," + photo.writerIndex() + "," + Math.min(1024, photo.writableBytes()); + sendResponse(channel, remoteAddress, imei, content); + } + private String decodeAlarm(Integer alarm) { if (alarm != null) { switch (alarm) { @@ -200,11 +208,14 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { return null; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + String imei = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; } + String index = parser.next(); + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -243,6 +254,11 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(network); + DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + String response = index + ",A03," + dateFormat.format(new Date()); + sendResponse(channel, remoteAddress, imei, response); + return position; } -- cgit v1.2.3 From 7aa230b9ddcd5540e7ff9c9b3d9bcf5119175c46 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 17 Sep 2022 20:46:40 +0100 Subject: Xexun2 Encoder update --- src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index c315cab30..8f3fa5672 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -40,7 +40,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(Xexun2ProtocolDecoder.MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); - buf.writeShort(message.capacity()); + buf.writeShort(message.readableBytes()); buf.writeShort(Checksum.ip(message.nioBuffer())); buf.writeBytes(message); buf.writeShort(Xexun2ProtocolDecoder.FLAG); -- cgit v1.2.3 From 79ecdf701ce5db5505c366bafe4f04e4d565ec7d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 16:57:29 -0700 Subject: Fix temperature decoding --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 9122eb362..eb8c1c466 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.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. @@ -293,7 +293,9 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 51: case 52: value = buf.readByte(); - position.set(Position.PREFIX_TEMP + (j + 2 - 45), (value != 0x80) ? value : null); + position.set( + Position.PREFIX_TEMP + (j + 2 - 45), + (value != (byte) 0x80) ? value : null); break; default: buf.skipBytes(getItemLength(j + 1)); -- cgit v1.2.3 From 3a6219d8cc2a014a78d53f9ca9695558ffd72926 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 16:58:10 -0700 Subject: Remove unnecessary assignment --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index eb8c1c466..20e10cdcd 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -196,7 +196,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < bits.length(); j++) { if (bits.get(j)) { - int value = 0; + int value; switch (j + 1) { case 1: -- cgit v1.2.3 From 2d36cb5e0bbad23064d75f1f9364094b3e2fefa5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 17:00:48 -0700 Subject: Some Navis improvements --- src/main/java/org/traccar/protocol/NavisProtocolDecoder.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java index 53631bd4e..77158b315 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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,7 +24,6 @@ import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; -import org.traccar.helper.Checksum.Algorithm; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -591,10 +590,8 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { private void sendFlexReply(Channel channel, ByteBuf data) { if (channel != null) { - ByteBuf cs = Unpooled.buffer(1); - cs.writeByte(Checksum.crc8(new Algorithm(8, 0x31, 0xFF, false, false, 0x00), data.nioBuffer())); - - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(data, cs), channel.remoteAddress())); + data.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, data.nioBuffer())); + channel.writeAndFlush(new NetworkMessage(data, channel.remoteAddress())); } } -- cgit v1.2.3 From 6864e0a0a067f432bead08331404d4b141959a64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 17:26:52 -0700 Subject: Navtelecom fuel temperature --- .../java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 20e10cdcd..08b1a8d0f 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -278,11 +278,11 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 42: case 43: value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + (j + 2 - 38), (value < 65500) ? value : null); + position.set("fuel" + (j + 2 - 38), (value < 65500) ? value : null); break; case 44: value = buf.readUnsignedShortLE(); - position.set("rs232Fuel", (value < 65500) ? value : null); + position.set(Position.KEY_FUEL_LEVEL, (value < 65500) ? value : null); break; case 45: case 46: @@ -297,6 +297,14 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { Position.PREFIX_TEMP + (j + 2 - 45), (value != (byte) 0x80) ? value : null); break; + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + position.set("fuelTemp" + (j + 2 - 78), (int) buf.readByte()); + break; default: buf.skipBytes(getItemLength(j + 1)); break; -- cgit v1.2.3 From 43e04167d35c9f68eb5850f6e7e9f2723400957f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 09:26:22 -0700 Subject: Decode TAT100 cell info --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 44 +++++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index ff1f52eb1..4671a1088 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -342,16 +342,40 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeNetwork(Position position) { - Integer cid = (Integer) position.getAttributes().remove("cid"); - Integer lac = (Integer) position.getAttributes().remove("lac"); - if (cid != null && lac != null) { - CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); - long operator = position.getInteger(Position.KEY_OPERATOR); - if (operator >= 1000) { - cellTower.setOperator(operator); + private void decodeCell( + Position position, Network network, String mncKey, String lacKey, String cidKey, String rssiKey) { + if (position.hasAttribute(mncKey) && position.hasAttribute(lacKey) && position.hasAttribute(cidKey)) { + CellTower cellTower = CellTower.from( + getConfig().getInteger(Keys.GEOLOCATION_MCC), + (Integer) position.getAttributes().remove(mncKey), + (Integer) position.getAttributes().remove(lacKey), + (Integer) position.getAttributes().remove(cidKey)); + cellTower.setSignalStrength((Integer) position.getAttributes().remove(rssiKey)); + network.addCellTower(cellTower); + } + } + + private void decodeNetwork(Position position, String model) { + if ("TAT100".equals(model)) { + Network network = new Network(); + decodeCell(position, network, "io1200", "io287", "io288", "io289"); + decodeCell(position, network, "io1201", "io290", "io291", "io292"); + decodeCell(position, network, "io1202", "io293", "io294", "io295"); + decodeCell(position, network, "io1203", "io296", "io297", "io298"); + if (network.getCellTowers() != null) { + position.setNetwork(network); + } + } else { + Integer cid = (Integer) position.getAttributes().remove("cid"); + Integer lac = (Integer) position.getAttributes().remove("lac"); + if (cid != null && lac != null) { + CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); + long operator = position.getInteger(Position.KEY_OPERATOR); + if (operator >= 1000) { + cellTower.setOperator(operator); + } + position.setNetwork(new Network(cellTower)); } - position.setNetwork(new Network(cellTower)); } } @@ -545,7 +569,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - decodeNetwork(position); + decodeNetwork(position, model); } -- cgit v1.2.3 From 4de8efe1ef0810af492c161bfc1d3200958d75d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 10:01:28 -0700 Subject: Refactor M-5000/10000 decoding --- src/main/java/org/traccar/helper/NMEA.java | 126 --------------------- .../traccar/protocol/PiligrimProtocolDecoder.java | 125 ++++++++------------ .../protocol/PiligrimProtocolDecoderTest.java | 4 + 3 files changed, 52 insertions(+), 203 deletions(-) delete mode 100644 src/main/java/org/traccar/helper/NMEA.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/NMEA.java b/src/main/java/org/traccar/helper/NMEA.java deleted file mode 100644 index cae47a8f6..000000000 --- a/src/main/java/org/traccar/helper/NMEA.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.traccar.helper; - -import java.util.HashMap; -import java.util.Map; - - -public class NMEA { - - // fucking java interfaces - interface SentenceParser { - public boolean parse(String[] tokens, GPSPosition position); - } - - // utils - static float Latitude2Decimal(String lat, String NS) { - float med = Float.parseFloat(lat.substring(2)) / 60.0f; - med += Float.parseFloat(lat.substring(0, 2)); - if (NS.startsWith("S")) { - med = -med; - } - return med; - } - - static float Longitude2Decimal(String lon, String WE) { - float med = Float.parseFloat(lon.substring(3)) / 60.0f; - med += Float.parseFloat(lon.substring(0, 3)); - if (WE.startsWith("W")) { - med = -med; - } - return med; - } - - // parsers - class GPGGA implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.time = Float.parseFloat(tokens[1]); - position.lat = Latitude2Decimal(tokens[2], tokens[3]); - position.lon = Longitude2Decimal(tokens[4], tokens[5]); - position.quality = Integer.parseInt(tokens[6]); - position.altitude = Float.parseFloat(tokens[9]); - return true; - } - } - - class GPGGL implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.lat = Latitude2Decimal(tokens[1], tokens[2]); - position.lon = Longitude2Decimal(tokens[3], tokens[4]); - position.time = Float.parseFloat(tokens[5]); - return true; - } - } - - class GPRMC implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.time = Float.parseFloat(tokens[1]); - position.lat = Latitude2Decimal(tokens[3], tokens[4]); - position.lon = Longitude2Decimal(tokens[5], tokens[6]); - position.velocity = Float.parseFloat(tokens[7]); - position.dir = Float.parseFloat(tokens[8]); - return true; - } - } - - class GPVTG implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.dir = Float.parseFloat(tokens[3]); - return true; - } - } - - class GPRMZ implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.altitude = Float.parseFloat(tokens[1]); - return true; - } - } - - public class GPSPosition { - public float time = 0.0f; - public float lat = 0.0f; - public float lon = 0.0f; - public boolean fixed = false; - public int quality = 0; - public float dir = 0.0f; - public float altitude = 0.0f; - public float velocity = 0.0f; - - public void updatefix() { - fixed = quality > 0; - } - - public String toString() { - return String.format("POSITION: lat: %f, lon: %f, time: %f, Q: %d, dir: %f, alt: %f, vel: %f", lat, lon, time, quality, dir, altitude, velocity); - } - } - - GPSPosition position = new GPSPosition(); - - private static final Map sentenceParsers = new HashMap(); - - public NMEA() { - sentenceParsers.put("GPGGA", new GPGGA()); - sentenceParsers.put("GPGGL", new GPGGL()); - sentenceParsers.put("GPRMC", new GPRMC()); - sentenceParsers.put("GPRMZ", new GPRMZ()); - //only really good GPS devices have this sentence but ... - sentenceParsers.put("GPVTG", new GPVTG()); - } - - public GPSPosition parse(String line) { - - if (line.startsWith("$")) { - String nmea = line.substring(1); - String[] tokens = nmea.split(","); - String type = tokens[0]; - //TODO check crc - if (sentenceParsers.containsKey(type)) { - sentenceParsers.get(type).parse(tokens, position); - } - position.updatefix(); - } - - return position; - } -} diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 6ca9b0795..34c879cb8 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2020 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. @@ -21,27 +21,23 @@ 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.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.WebDataHandler; -import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; -import org.traccar.helper.NMEA; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; -import java.util.Date; import java.util.LinkedList; import java.util.List; +import java.util.regex.Pattern; public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(WebDataHandler.class); - public PiligrimProtocolDecoder(Protocol protocol) { super(protocol); } @@ -54,6 +50,21 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { public static final int MSG_GPS_SENSORS = 0xF2; public static final int MSG_EVENTS = 0xF3; + private static final Pattern PATTERN = new PatternBuilder() + .expression("[^$]+") + .text("$GPRMC,") + .number("(dd)(dd)(dd).d+,") // time (hhmmss) + .expression("([AV]),") // validity + .number("(dd)(dd.d+),") // latitude + .expression("([NS]),") + .number("(d{2,3})(dd.d+),") // longitude + .expression("([EW]),") + .number("(d+.d+),") // speed + .number("(d+.d+),") // course + .number("(dd)(dd)(dd),") // date (ddmmyy) + .any() + .compile(); + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -157,82 +168,42 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } return positions; + } else if (uri.startsWith("/push.do")) { + sendResponse(channel, "PUSH.DO: OK"); - /* Getting payload */ - ByteBuf contentStream = request.content(); - byte[] payloadBytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; - contentStream.readBytes(payloadBytes); - String payload = new String(payloadBytes); - - /* Payload structure: - * &phone&message - */ - String[] payloadParts = payload.split("&"); - /* LOGGER.debug("Payload parts: " + Arrays.toString(payloadParts)); */ - String phoneNumber = payloadParts[1].substring(15); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber.substring(1)); + String sentence = request.content().toString(StandardCharsets.US_ASCII); + + String[] parts = sentence.split("&"); + String phone = parts[1].substring(16); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phone); if (deviceSession == null) { return null; } - /* TODO: use keys for flags in 'positions'. */ - String message = payloadParts[2].substring(8).replaceFirst("[a-zA-Z! ]*; ", ""); - /* LOGGER.debug("Phone number: " + phoneNumber); */ - /* LOGGER.debug("Message: " + message); */ - - if (message.startsWith("$GPRMC")) { - /* Supported message structure: - * GPS NMEA Command; GSM info; Unknown; Battery voltage? - * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M - */ - LOGGER.debug("Supported message"); - - String[] messageParts = message.split(";"); - /* LOGGER.debug("Message parts: " + Arrays.toString(messageParts)); */ - - /* Parsing GPS */ - String unprocessedGpsCommand = messageParts[0]; - - /* Getting rid of checksum */ - String gpsCommand = unprocessedGpsCommand.replaceFirst("A,V[*].*", ""); - /* LOGGER.debug("GPS command: " + gpsCommand); */ - - NMEA gpsParser = new NMEA(); - - NMEA.GPSPosition gpsPosition = gpsParser.parse(gpsCommand); - - /* LOGGER.debug("Time: " + gpsPosition.time); */ - /* LOGGER.debug("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ - /* LOGGER.debug("Speed over ground: " + gpsPosition.velocity + " knots"); */ - - /* Parsing other fields */ - /* String gsmInfo = messageParts[1]; */ - /* String unknown = messageParts[2]; */ - String batteryInfo = messageParts[messageParts.length - 1].substring(7).substring(0, 3); - /* LOGGER.debug("Battery: " + batteryInfo); */ - - /* Constructing response */ - Position position = new Position(getProtocolName()); - - position.setDeviceId(deviceSession.getDeviceId()); - position.setValid(true); - position.setLatitude(gpsPosition.lat); - position.setLongitude(gpsPosition.lon); - position.setTime(new Date(System.currentTimeMillis())); - position.setSpeed(gpsPosition.velocity); - position.setCourse(gpsPosition.dir); - position.setAccuracy(gpsPosition.quality); - position.setAltitude(gpsPosition.altitude); - position.set(Position.KEY_BATTERY, Integer.parseInt(batteryInfo) / 100); - - LOGGER.debug("Supported message finish"); - - return position; - } else { - LOGGER.error("Unsupported message"); + Parser parser = new Parser(PATTERN, parts[2]); + if (!parser.matches()) { + return null; } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder() + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + return position; + } return null; diff --git a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java index 475ac0125..0dd00462d 100644 --- a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java @@ -15,6 +15,10 @@ public class PiligrimProtocolDecoderTest extends ProtocolTest { "/bingps?imei=868204005544720&csq=18&vout=00&vin=4050&dataid=00000000", binary("fff2200d4110061a32354f3422310062000a0005173b0000a101000300005e00fff2200d4110100932354f2b22310042000b000e173b00009f01000700006000"))); + verifyPosition(decoder, request(HttpMethod.POST, + "/push.do", + buffer("&phoneNumber=%2B+78000000000&message=ALARM KEY; $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M"))); + } } -- cgit v1.2.3 From 8532bffcec8e239c6699845e09e63da927f51d9a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 10:47:58 -0700 Subject: Refactor NDTPv6 protocol --- .../org/traccar/protocol/NDTPv6FrameDecoder.java | 32 --- .../java/org/traccar/protocol/NDTPv6Protocol.java | 26 -- .../traccar/protocol/NDTPv6ProtocolDecoder.java | 309 --------------------- .../traccar/protocol/NDTPv6ProtocolEncoder.java | 38 --- .../org/traccar/protocol/NdtpV6FrameDecoder.java | 32 +++ .../java/org/traccar/protocol/NdtpV6Protocol.java | 39 +++ .../traccar/protocol/NdtpV6ProtocolDecoder.java | 203 ++++++++++++++ .../traccar/protocol/NdtpV6ProtocolEncoder.java | 42 +++ 8 files changed, 316 insertions(+), 405 deletions(-) delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6Protocol.java delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java 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 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java b/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java deleted file mode 100644 index c869b11a4..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 deleted file mode 100644 index 78dc11b50..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6Protocol.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 deleted file mode 100644 index 788afd65b..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * 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 deleted file mode 100644 index af0dd58f9..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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; - } - } -} 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..5b610013a --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java @@ -0,0 +1,32 @@ +/* + * 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.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..ce0dbbef2 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6Protocol.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.string.StringEncoder; +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 StringEncoder()); + 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..35cb0bae8 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java @@ -0,0 +1,203 @@ +/* + * 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.Checksum; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.Date; + +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; + + private static final int NPH_RESULT = 0; + + private static final int NPH_SRV_GENERIC_CONTROLS = 0; + private static final int NPH_SRV_NAVDATA = 1; + + private static final int NPH_SGC_RESULT = NPH_RESULT; + private static final int NPH_SGC_CONN_REQUEST = 100; + + private static final int NPH_SND_RESULT = NPH_RESULT; + + private void sendResponse( + Channel channel, int serviceId, long requestId) { + + ByteBuf content = Unpooled.buffer(); + content.writeShortLE(serviceId); + content.writeIntLE(NPH_SND_RESULT); + content.writeIntLE((int) requestId); + content.writeIntLE(NPH_RESULT_OK); + + ByteBuf response = Unpooled.buffer(); + response.writeBytes(SIGNATURE); + response.writeShortLE(content.readableBytes()); + response.writeShortLE(NPL_FLAG_CRC); // flags + response.writeShort(Checksum.crc16(Checksum.CRC16_MODBUS, content.nioBuffer())); + response.writeByte(NPL_TYPE_NPH); // type + response.writeIntLE(NPL_ADDRESS_SERVER); // peer address + response.writeShortLE(0); // request id + response.writeBytes(content); + content.release(); + + 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) { + + short itemType; + short itemIndex; + + itemType = buf.readUnsignedByte(); + itemIndex = buf.readUnsignedByte(); + if (itemType == MAIN_NAV_DATA && (itemIndex == 0 || itemIndex == 1)) { + + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setLongitude(buf.readIntLE() / 10000000.0); + position.setLatitude(buf.readIntLE() / 10000000.0); + + short flags = buf.readUnsignedByte(); + 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); + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + position.setCourse(buf.readUnsignedShortLE()); + + position.set(Position.KEY_ODOMETER, buf.readUnsignedShortLE()); + position.setAltitude(buf.readShortLE()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_PDOP, buf.readUnsignedByte()); + } + + itemType = buf.readUnsignedByte(); + itemIndex = buf.readUnsignedByte(); + if (itemType == ADDITIONAL_NAV_DATA && itemIndex == 0) { + + position.set(Position.KEY_BATTERY_LEVEL, Math.max((buf.readUnsignedShortLE() - 3600) / 6, 100)); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShortLE()); + + buf.readUnsignedByte(); // inputs + buf.readUnsignedByte(); // outputs + buf.readUnsignedShortLE(); // in1 count + buf.readUnsignedShortLE(); // in2 count + buf.readUnsignedShortLE(); // in3 count + buf.readUnsignedShortLE(); // in4 count + buf.readUnsignedIntLE(); // track length + + position.set(Position.KEY_ANTENNA, buf.readUnsignedByte()); + position.set(Position.KEY_GPS, buf.readUnsignedByte()); + position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedByte() * 200); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + + buf.skipBytes(2); // signature + buf.readUnsignedShortLE(); // length + buf.readUnsignedShortLE(); // connection flags + buf.readUnsignedShortLE(); // checksum + buf.readUnsignedByte(); // type + buf.readUnsignedIntLE(); // address + buf.readUnsignedShortLE(); // identification + + int serviceId = buf.readUnsignedShortLE(); + int serviceType = buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); // request flags + long requestId = buf.readUnsignedIntLE(); + + if (deviceSession == null && serviceId == NPH_SRV_GENERIC_CONTROLS && serviceType == NPH_SGC_CONN_REQUEST) { + + buf.readUnsignedShortLE(); // version major + buf.readUnsignedShortLE(); // version minor + buf.readUnsignedShortLE(); // connection flags + + int deviceId = buf.readUnsignedShortLE(); + Position position = new Position(getProtocolName()); + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResponse(channel, serviceId, requestId); + } + + 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) { + sendResponse(channel, serviceId, requestId); + } + + decodeData(buf, position); + + 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..7aac8658a --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java @@ -0,0 +1,42 @@ +/* + * 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 org.traccar.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.model.Command; + +public class NdtpV6ProtocolEncoder extends BaseProtocolEncoder { + + public NdtpV6ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object encodeCommand(Command command) { + switch (command.getType()) { + case Command.TYPE_IDENTIFICATION: + return "BB+IDNT"; + case Command.TYPE_REBOOT_DEVICE: + return "BB+RESET"; + case Command.TYPE_POSITION_SINGLE: + return "BB+RRCD"; + default: + return null; + } + } + +} -- cgit v1.2.3 From 5612d29b74a1c5ded13955565cf1b48f2307813c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 11:31:41 -0700 Subject: Refactor G1RUS protocol --- .../org/traccar/protocol/G1rusFrameDecoder.java | 49 +++ .../java/org/traccar/protocol/G1rusProtocol.java | 18 +- .../org/traccar/protocol/G1rusProtocolDecoder.java | 412 +++++---------------- 3 files changed, 165 insertions(+), 314 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/G1rusFrameDecoder.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java b/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java new file mode 100644 index 000000000..8c67207ad --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java @@ -0,0 +1,49 @@ +/* + * 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 io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class G1rusFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + ByteBuf result = Unpooled.buffer(); + + while (buf.isReadable()) { + int b = buf.readUnsignedByte(); + if (b == 0x1B) { + int ext = buf.readUnsignedByte(); + if (ext == 0x00) { + result.writeByte(0x1B); + } else { + result.writeByte(0xF8); + } + } else { + result.writeByte(b); + } + } + + return result; + } + +} diff --git a/src/main/java/org/traccar/protocol/G1rusProtocol.java b/src/main/java/org/traccar/protocol/G1rusProtocol.java index 0d77a8add..f1823762d 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocol.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocol.java @@ -1,6 +1,20 @@ +/* + * 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.PipelineBuilder; @@ -16,9 +30,11 @@ public class G1rusProtocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new G1rusFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new G1rusProtocolDecoder(G1rusProtocol.this)); } }); } + } diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index b1b7230e1..e974e446d 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -1,20 +1,30 @@ +/* + * 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 com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; -import com.google.common.primitives.Shorts; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import org.traccar.helper.BitUtil; import org.traccar.model.Position; -import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import java.net.SocketAddress; -import java.text.SimpleDateFormat; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -24,352 +34,128 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); + public static final int MSG_HEARTBEAT = 0; + public static final int MSG_REGULAR = 1; + public static final int MSG_SMS_FORWARD = 2; + public static final int MSG_SERIAL = 3; + public static final int MSG_MIXED = 4; - /* Constants */ - private static final int G1RUS_HEAD_TAIL = 0xF8; - - private static final int G1RUS_TYPE_HEARTBEAT = 0; - - private static final int G1RUS_TYPE_BCD_MASK = 0b00111111; - private static final int G1RUS_TYPE_REGULAR = 1; - private static final int G1RUS_TYPE_SMS_FORWARD = 2; - private static final int G1RUS_TYPE_SERIAL_PASS_THROUGH = 3; - private static final int G1RUS_TYPE_MIXED = 4; - - private static final int G1RUS_TYPE_EVENT_MASK = 0b01000000; - private static final int G1RUS_TYPE_NON_EVENT = 0; - private static final int G1RUS_TYPE_EVENT = 1; - - private static final int G1RUS_TYPE_IMEI_MASK = 0b10000000; - private static final int G1RUS_TYPE_IMEI_LONG = 0; - private static final int G1RUS_TYPE_IMEI_SHORT = 1; - - private static final int G1RUS_DATA_SYS_MASK = 0b00000001; - private static final int G1RUS_DATA_GPS_MASK = 0b00000010; - private static final int G1RUS_DATA_GSM_MASK = 0b00000100; - private static final int G1RUS_DATA_COT_MASK = 0b00001000; - private static final int G1RUS_DATA_ADC_MASK = 0b00010000; - private static final int G1RUS_DATA_DTT_MASK = 0b00100000; - /* Reserved */ - private static final int G1RUS_DATA_ETD_MASK = 0b10000000; - - private static final int G1RUS_GPS_SIGN_MASK = 0b00000001; - private static final int G1RUS_GPS_POS_MASK = 0b00000010; - private static final int G1RUS_GPS_SPD_MASK = 0b00000100; - private static final int G1RUS_GPS_AZTH_MASK = 0b00001000; - private static final int G1RUS_GPS_ALT_MASK = 0b00010000; - private static final int G1RUS_GPS_HDOP_MASK = 0b00100000; - private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; - private static final int G1RUS_GPS_STAT_MASK = 0b10000000; - - private static final int G1RUS_ADC_DATA_MASK = 0b0000111111111111; + private String readString(ByteBuf buf) { + int length = buf.readUnsignedByte() & 0xF; + return buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + } - private static final int G1RUS_ESCAPE_CHAR = 0x1B; + private Position decodeRegular(DeviceSession deviceSession, ByteBuf buf, int type) { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setTime(new Date((buf.readUnsignedIntLE() + 946684800) * 1000L)); - private short readUnsignedByteUnescaped(ByteBuf buf) { - short first = buf.readUnsignedByte(); - if (first != G1RUS_ESCAPE_CHAR) { - return first; - } else { /* first == 0x1B */ - byte second = (byte) buf.readUnsignedByte(); - if (second == 0x00) { - return first; - } else { /* second == 0xE3 */ - return (short) 0xF8; - } + if (BitUtil.check(type, 6)) { + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); } - } + int dataMask = buf.readUnsignedShort(); - private void skipBytesUnescaped(ByteBuf buf, int howMany) { - for (int i = 0; i < howMany; ++i) { - readUnsignedByteUnescaped(buf); + if (BitUtil.check(dataMask, 0)) { + buf.readUnsignedByte(); // length + readString(buf); // device name + position.set(Position.KEY_VERSION_FW, readString(buf)); + position.set(Position.KEY_VERSION_HW, readString(buf)); } - } - - private void readBytesUnescaped(ByteBuf buf, byte[] to) { - for (int i = 0; i < to.length; ++i) { - to[i] = (byte) readUnsignedByteUnescaped(buf); + if (BitUtil.check(dataMask, 1)) { + buf.readUnsignedByte(); // length + int locationMask = buf.readUnsignedShort(); + if (BitUtil.check(locationMask, 0)) { + int validity = buf.readUnsignedByte(); + position.set(Position.KEY_SATELLITES, BitUtil.to(validity, 5)); + position.setValid(BitUtil.between(validity, 5, 7) == 2); + } + if (BitUtil.check(locationMask, 1)) { + position.setLatitude(buf.readInt() / 1000000.0); + position.setLongitude(buf.readInt() / 1000000.0); + } + if (BitUtil.check(locationMask, 2)) { + position.setSpeed(buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 3)) { + position.setCourse(buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 4)) { + position.setAltitude(buf.readShort()); + } + if (BitUtil.check(locationMask, 5)) { + position.set(Position.KEY_HDOP, buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 6)) { + position.set(Position.KEY_VDOP, buf.readUnsignedShort()); + } } - } - private void readBytesUnescaped(ByteBuf buf, byte[] to, int dstIndex, int length) { - for (int i = dstIndex; i < length; ++i) { - to[i] = (byte) readUnsignedByteUnescaped(buf); + if (BitUtil.check(dataMask, 2)) { + buf.skipBytes(buf.readUnsignedByte()); } - } - - - private int readUnsignedShortUnescaped(ByteBuf buf) { - byte[] shortBuf = new byte[2]; - readBytesUnescaped(buf, shortBuf); - return Shorts.fromByteArray(shortBuf); - } - - private int readIntUnescaped(ByteBuf buf) { - byte[] intBuf = new byte[4]; - readBytesUnescaped(buf, intBuf); - return Ints.fromByteArray(intBuf); - } - - - private void decodeSYSSub(ByteBuf buf) { - LOGGER.debug(""); - - skipBytesUnescaped(buf, 1); /* Total length */ - - /* NOTE: assuming order: - * Device name -> Firmware version -> Hardware version. - * TODO: actually check it. - */ - - /* Device name */ - short devNameLen = readUnsignedByteUnescaped(buf); - byte[] devName = new byte[devNameLen & 0xF]; - readBytesUnescaped(buf, devName); - String devNameString = new String(devName); - LOGGER.debug("Device name: " + devNameString); - - /* Firmware version */ - short firmwareLen = readUnsignedByteUnescaped(buf); - byte[] firmware = new byte[firmwareLen & 0xF]; - readBytesUnescaped(buf, firmware); - String firmwareString = new String(firmware); - LOGGER.debug("Firmware version: " + firmwareString); - - /* Hardware version */ - short hardwareLen = readUnsignedByteUnescaped(buf); - byte[] hardware = new byte[hardwareLen & 0xF]; - readBytesUnescaped(buf, hardware); - String hardwareString = new String(hardware); - LOGGER.debug("Hardware version: " + hardwareString); - - LOGGER.debug(""); - } - - - private void decodeGPSSub(ByteBuf buf, Position position) { - LOGGER.debug(""); - - skipBytesUnescaped(buf, 1); /* Total length */ - - int subMask = readUnsignedShortUnescaped(buf); - if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { - short signValid = readUnsignedByteUnescaped(buf); - LOGGER.debug("Fix sign: " + ((signValid & 0b1100000) >> 5)); - LOGGER.debug("Satellite number: " + (signValid & 0b0011111)); - position.setValid(((signValid & 0b1100000) >> 5) == 2); - position.set(Position.KEY_SATELLITES, signValid & 0b0011111); - } - if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { - byte[] posBuf = new byte[4]; - readBytesUnescaped(buf, posBuf); - position.setLatitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.debug("Latitude: " + position.getLatitude()); - - readBytesUnescaped(buf, posBuf); - position.setLongitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.debug("Longitude: " + position.getLongitude()); - } - if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { - position.setSpeed(readUnsignedShortUnescaped(buf)); - LOGGER.debug("Speed: " + position.getSpeed()); + if (BitUtil.check(dataMask, 3)) { + buf.skipBytes(buf.readUnsignedByte()); } - if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { - position.setCourse(readUnsignedShortUnescaped(buf)); - LOGGER.debug("Course: " + position.getCourse()); - } - if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { - position.setAltitude(readUnsignedShortUnescaped(buf)); - LOGGER.debug("Altitude: " + position.getAltitude()); - } - if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { - position.set(Position.KEY_HDOP, readUnsignedShortUnescaped(buf)); - LOGGER.debug("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); - } - if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { - position.set(Position.KEY_VDOP, readUnsignedShortUnescaped(buf)); - LOGGER.debug("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); - } - - LOGGER.debug(""); - } - - - private int getADValue(int rawValue) { - final int AD_MIN = -10; - final int AD_MAX = 100; - - return rawValue * (AD_MAX - AD_MIN) / 4096 + AD_MIN; - } - - - private void decodeADCSub(ByteBuf buf, Position position) { - LOGGER.debug(""); - - skipBytesUnescaped(buf, 1); - - /* NOTE: assuming order: - * External battery voltage -> Backup battery voltage -> Device temperature voltage. - * TODO: actually check this. - */ - - int externalVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.debug("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); - - int backupVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.debug("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); - position.set(Position.KEY_BATTERY, getADValue(backupVoltage)); - - int temperature = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.debug("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); - position.set(Position.KEY_DEVICE_TEMP, getADValue(temperature)); - LOGGER.debug(""); - } - - - private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, short packetType) { - int timestamp_ = readIntUnescaped(buf); - long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ - LOGGER.debug("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); - - if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { - skipBytesUnescaped(buf, 1); /* Event ID */ + if (BitUtil.check(dataMask, 4)) { + buf.readUnsignedByte(); // length + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 110 / 4096 - 10); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 110 / 4096 - 10); + position.set(Position.KEY_DEVICE_TEMP, buf.readUnsignedShort() * 110 / 4096 - 10); } - DeviceSession deviceSession = null; - Position position = null; - - int dataUploadingMask = readUnsignedShortUnescaped(buf); - if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { - decodeSYSSub(buf); + if (BitUtil.check(dataMask, 5)) { + buf.skipBytes(buf.readUnsignedByte()); } - if ((dataUploadingMask & G1RUS_DATA_GPS_MASK) == G1RUS_DATA_GPS_MASK) { - deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(imei)); - if (deviceSession == null) { - return null; - } - position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(new Date(timestamp)); - decodeGPSSub(buf, position); - } - if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } - if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } - if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { - if (deviceSession == null) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } else { - decodeADCSub(buf, position); - } - } - if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } - if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); + if (BitUtil.check(dataMask, 7)) { + buf.skipBytes(buf.readUnsignedByte()); } return position; } - - private Object decodeSMSForward(ByteBuf buf) { - return null; - } - - - private Object decodeSerialPassThrough(ByteBuf buf) { - return null; - } - - - private void printPacketType(short packetType) { - LOGGER.debug("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : - "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + - "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + - "[" + ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR ? "REGULAR" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD ? "SMS FORWARD" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH ? "PASS THROUGH" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED ? "MIXED PACKED" : "RESERVED/INVALID") + "]")); - } - - @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ByteBuf buf = (ByteBuf) msg; - if (buf.readUnsignedByte() != G1RUS_HEAD_TAIL) { + int type = buf.readUnsignedByte(); + String imei = String.valueOf(buf.readLong()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { return null; } - LOGGER.debug("Protocol version: " + readUnsignedByteUnescaped(buf)); - - short packetType = readUnsignedByteUnescaped(buf); - printPacketType(packetType); - - byte[] imei = new byte[8]; - readBytesUnescaped(buf, imei, 0, 7); - long imeiLong = Longs.fromByteArray(imei); - LOGGER.debug("IMEI: " + imeiLong); + if (BitUtil.to(type, 6) == MSG_REGULAR) { - List positions = null; + return decodeRegular(deviceSession, buf, type); - if (packetType == G1RUS_TYPE_HEARTBEAT) { - return null; - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - positions = new LinkedList<>(); - Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, packetType); - if (position != null) { - positions.add(position); - } - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { - return decodeSMSForward(buf); - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { - return decodeSerialPassThrough(buf); - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED) { - positions = new LinkedList<>(); + } else if (BitUtil.to(type, 6) == MSG_MIXED) { + List positions = new LinkedList<>(); while (buf.readableBytes() > 5) { - int subPacketLength = readUnsignedShortUnescaped(buf); - short subPacketType = readUnsignedByteUnescaped(buf); - printPacketType(subPacketType); - - if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, subPacketType); - if (position != null) { - positions.add(position); - } + int length = buf.readUnsignedShort(); + int subtype = buf.readUnsignedByte(); + if (BitUtil.to(subtype, 6) == MSG_REGULAR) { + positions.add(decodeRegular(deviceSession, buf, subtype)); } else { - skipBytesUnescaped(buf, subPacketLength - 1); + buf.skipBytes(length); } - /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { - skipBytesUnescaped(buf, subPacketLength - 1); - *//*decodeSMSForward(buf);*//* - } else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { - skipBytesUnescaped(buf, subPacketLength - 1); - *//*decodeSerialPassThrough(buf);*//* - }*/ } - } else { - LOGGER.error("Unknown packet type!"); - } + return positions.isEmpty() ? null : positions; - skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ - short tail = buf.readUnsignedByte(); - if (tail == G1RUS_HEAD_TAIL) { - LOGGER.debug("Tail: OK"); - } else { - LOGGER.error("Tail: FAIL!"); } - return positions; + buf.skipBytes(2); + buf.readUnsignedByte(); // tail + + return null; + } + } -- cgit v1.2.3 From 18513d7949a2be933541c45728a1d466be2b50a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 19 Sep 2022 17:23:36 -0700 Subject: Decode TR08X tampering alarm --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 1 + src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 7eeee5efb..a93c11cbc 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -410,6 +410,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_LOW_BATTERY; case 0x11: return Position.ALARM_POWER_OFF; + case 0x0C: case 0x13: case 0x25: return Position.ALARM_TAMPERING; diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 1570dcf32..ebda38823 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78782526160913063918c002780fab0c44750f00040008027f14084c0038420600030c020007398e0d0a"), + Position.KEY_ALARM, Position.ALARM_TAMPERING); + verifyAttribute(decoder, binary( "7979000d940516090908081c030defbd2d0d0a"), Position.KEY_DOOR, true); -- cgit v1.2.3 From 561647947118a86256dbb584f6da450334462739 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 19 Sep 2022 19:07:26 -0700 Subject: Refactor overspeed handling --- src/main/java/org/traccar/config/Keys.java | 14 --- .../traccar/handler/events/MotionEventHandler.java | 15 --- .../handler/events/OverspeedEventHandler.java | 91 ++++++----------- .../org/traccar/session/ConnectionManager.java | 34 +------ src/main/java/org/traccar/session/DeviceState.java | 18 ++-- .../handler/events/MotionEventHandlerTest.java | 21 ---- .../handler/events/OverspeedEventHandlerTest.java | 108 ++++++--------------- 7 files changed, 70 insertions(+), 231 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e6c3656da..ea394d914 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -326,13 +326,6 @@ public final class Keys { List.of(KeyType.SERVER, KeyType.DEVICE), 0.0); - /** - * If true, the event is generated once at the beginning of overspeeding period. - */ - public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new BooleanConfigKey( - "event.overspeed.notRepeat", - List.of(KeyType.CONFIG)); - /** * Minimal over speed duration to trigger the event. Value in seconds. */ @@ -598,13 +591,6 @@ public final class Keys { List.of(KeyType.CONFIG), 600L); - /** - * Force additional state check when device status changes to 'offline' or 'unknown'. Default false. - */ - public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new BooleanConfigKey( - "status.updateDeviceState", - List.of(KeyType.CONFIG)); - /** * List of protocol names to ignore offline status. Can be useful to not trigger status change when devices are * configured to disconnect after reporting a batch of data. diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 1be1896ef..7ef9ec21d 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -54,21 +54,6 @@ public class MotionEventHandler extends BaseEventHandler { return Collections.singletonMap(event, position); } - public Map updateMotionState(DeviceState deviceState) { - Map result = null; - if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { - boolean newMotion = !deviceState.getMotionState(); - Position motionPosition = deviceState.getMotionPosition(); - long currentTime = System.currentTimeMillis(); - long motionTime = motionPosition.getFixTime().getTime() - + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); - if (motionTime <= currentTime) { - result = newEvent(deviceState, newMotion); - } - } - return result; - } - public Map updateMotionState(DeviceState deviceState, Position position) { return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 7f3675308..cfba56a38 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -42,7 +42,6 @@ public class OverspeedEventHandler extends BaseEventHandler { private final ConnectionManager connectionManager; private final CacheManager cacheManager; - private final boolean notRepeat; private final long minimalDuration; private final boolean preferLowest; @@ -50,66 +49,46 @@ public class OverspeedEventHandler extends BaseEventHandler { public OverspeedEventHandler(Config config, ConnectionManager connectionManager, CacheManager cacheManager) { this.connectionManager = connectionManager; this.cacheManager = cacheManager; - notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT); minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); } - private Map newEvent(DeviceState deviceState, double speedLimit) { - Position position = deviceState.getOverspeedPosition(); - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); - event.set(ATTRIBUTE_SPEED, deviceState.getOverspeedPosition().getSpeed()); - event.set(Position.KEY_SPEED_LIMIT, speedLimit); - event.setGeofenceId(deviceState.getOverspeedGeofenceId()); - deviceState.setOverspeedState(notRepeat); - deviceState.setOverspeedPosition(null); - deviceState.setOverspeedGeofenceId(0); - return Collections.singletonMap(event, position); - } - - public Map updateOverspeedState(DeviceState deviceState, double speedLimit) { - Map result = null; - if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() - && deviceState.getOverspeedPosition() != null && speedLimit != 0) { - long currentTime = System.currentTimeMillis(); - Position overspeedPosition = deviceState.getOverspeedPosition(); - long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (overspeedTime + minimalDuration <= currentTime) { - result = newEvent(deviceState, speedLimit); - } - } - return result; - } - public Map updateOverspeedState( DeviceState deviceState, Position position, double speedLimit, long geofenceId) { - Map result = null; - Boolean oldOverspeed = deviceState.getOverspeedState(); + boolean oldState = deviceState.getOverspeedState(); + if (oldState) { + boolean newState = position.getSpeed() > speedLimit; + if (newState) { + if (deviceState.getOverspeedTime() != null) { + long oldTime = deviceState.getOverspeedTime().getTime(); + long newTime = position.getFixTime().getTime(); + if (newTime - oldTime > minimalDuration) { - long currentTime = position.getFixTime().getTime(); - boolean newOverspeed = position.getSpeed() > speedLimit; - if (newOverspeed && !oldOverspeed) { - if (deviceState.getOverspeedPosition() == null) { - deviceState.setOverspeedPosition(position); - deviceState.setOverspeedGeofenceId(geofenceId); - } - } else if (oldOverspeed && !newOverspeed) { - deviceState.setOverspeedState(false); - deviceState.setOverspeedPosition(null); - deviceState.setOverspeedGeofenceId(0); - } else { - deviceState.setOverspeedPosition(null); - deviceState.setOverspeedGeofenceId(0); - } - Position overspeedPosition = deviceState.getOverspeedPosition(); - if (overspeedPosition != null) { - long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (newOverspeed && overspeedTime + minimalDuration <= currentTime) { - result = newEvent(deviceState, speedLimit); + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); + event.set(ATTRIBUTE_SPEED, position.getSpeed()); + event.set(Position.KEY_SPEED_LIMIT, speedLimit); + event.setGeofenceId(deviceState.getOverspeedGeofenceId()); + + deviceState.setOverspeedTime(null); + deviceState.setOverspeedGeofenceId(0); + + return Collections.singletonMap(event, position); + + } + } + } else { + deviceState.setOverspeedState(false); + deviceState.setOverspeedTime(null); + deviceState.setOverspeedGeofenceId(0); } + } else if (position != null && position.getSpeed() > speedLimit) { + deviceState.setOverspeedState(true); + deviceState.setOverspeedTime(position.getFixTime()); + deviceState.setOverspeedGeofenceId(geofenceId); } - return result; + + return null; } @Override @@ -156,16 +135,8 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - Map result = null; DeviceState deviceState = connectionManager.getDeviceState(deviceId); - - if (deviceState.getOverspeedState() == null) { - deviceState.setOverspeedState(position.getSpeed() > speedLimit); - deviceState.setOverspeedGeofenceId(position.getSpeed() > speedLimit ? overspeedGeofenceId : 0); - } else { - result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); - } - + Map result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 262a302af..c826b99db 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -15,7 +15,6 @@ */ package org.traccar.session; -import com.google.inject.Injector; import io.netty.channel.Channel; import io.netty.util.Timeout; import io.netty.util.Timer; @@ -28,9 +27,6 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceLookupService; import org.traccar.database.NotificationManager; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; -import org.traccar.helper.model.AttributeUtil; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Event; @@ -66,14 +62,12 @@ public class ConnectionManager implements BroadcastInterface { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); private final long deviceTimeout; - private final boolean updateDeviceState; private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); private final Map deviceStates = new ConcurrentHashMap<>(); - private final Injector injector; private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -90,10 +84,9 @@ public class ConnectionManager implements BroadcastInterface { @Inject public ConnectionManager( - Injector injector, Config config, CacheManager cacheManager, Storage storage, + Config config, CacheManager cacheManager, Storage storage, NotificationManager notificationManager, Timer timer, BroadcastService broadcastService, DeviceLookupService deviceLookupService) { - this.injector = injector; this.config = config; this.cacheManager = cacheManager; this.storage = storage; @@ -102,7 +95,6 @@ public class ConnectionManager implements BroadcastInterface { this.broadcastService = broadcastService; this.deviceLookupService = deviceLookupService; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT); - updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); broadcastService.registerListener(this); } @@ -246,15 +238,9 @@ public class ConnectionManager implements BroadcastInterface { break; case Device.STATUS_UNKNOWN: eventType = Event.TYPE_DEVICE_UNKNOWN; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } break; default: eventType = Event.TYPE_DEVICE_OFFLINE; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } break; } events.put(new Event(eventType, deviceId), null); @@ -297,24 +283,6 @@ public class ConnectionManager implements BroadcastInterface { deviceStates.put(deviceId, deviceState); } - public Map updateDeviceState(long deviceId) { - DeviceState deviceState = getDeviceState(deviceId); - Map result = new HashMap<>(); - - Map event = injector.getInstance(MotionEventHandler.class).updateMotionState(deviceState); - if (event != null) { - result.putAll(event); - } - - double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); - event = injector.getInstance(OverspeedEventHandler.class).updateOverspeedState(deviceState, speedLimit); - if (event != null) { - result.putAll(event); - } - - return result; - } - public synchronized void sendKeepalive() { for (Set userListeners : listeners.values()) { for (UpdateListener listener : userListeners) { diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java index b7248688a..f67b906c4 100644 --- a/src/main/java/org/traccar/session/DeviceState.java +++ b/src/main/java/org/traccar/session/DeviceState.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,6 +18,8 @@ package org.traccar.session; import org.traccar.model.Position; +import java.util.Date; + public class DeviceState { private Boolean motionState; @@ -40,24 +42,24 @@ public class DeviceState { return motionPosition; } - private Boolean overspeedState; + private boolean overspeedState; public void setOverspeedState(boolean overspeedState) { this.overspeedState = overspeedState; } - public Boolean getOverspeedState() { + public boolean getOverspeedState() { return overspeedState; } - private Position overspeedPosition; + private Date overspeedTime; - public void setOverspeedPosition(Position overspeedPosition) { - this.overspeedPosition = overspeedPosition; + public Date getOverspeedTime() { + return overspeedTime; } - public Position getOverspeedPosition() { - return overspeedPosition; + public void setOverspeedTime(Date overspeedTime) { + this.overspeedTime = overspeedTime; } private long overspeedGeofenceId; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 780d1b833..1f6212eec 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -69,27 +69,6 @@ public class MotionEventHandlerTest extends BaseTest { assertNull(deviceState.getMotionPosition()); } - @Test - public void testMotionWithStatus() throws Exception { - MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false, 0.01)); - - Position position = new Position(); - position.setTime(new Date(System.currentTimeMillis() - 360000)); - position.set(Position.KEY_MOTION, true); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(false); - deviceState.setMotionPosition(position); - - Map events = motionEventHandler.updateMotionState(deviceState); - - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); - assertTrue(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); - } - @Test public void testStopWithPositionIgnition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 46e142935..bbddbae72 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -11,118 +11,66 @@ import org.traccar.session.DeviceState; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; import java.util.TimeZone; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; public class OverspeedEventHandlerTest extends BaseTest { - private Date date(String time) throws ParseException { + private Position position(String time, double speed) throws ParseException { + Position position = new Position(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - return dateFormat.parse(time); + position.setTime(dateFormat.parse(time)); + position.setSpeed(speed); + return position; + } + + private void verifyState(DeviceState deviceState, boolean state, long geofenceId) { + assertEquals(state, deviceState.getOverspeedState()); + assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); } - private void testOverspeedWithPosition(boolean notRepeat, long geofenceId) throws ParseException { + private void testOverspeedWithPosition(long geofenceId) throws ParseException { Config config = new Config(); - config.setString(Keys.EVENT_OVERSPEED_NOT_REPEAT, String.valueOf(notRepeat)); config.setString(Keys.EVENT_OVERSPEED_MINIMAL_DURATION, String.valueOf(15)); config.setString(Keys.EVENT_OVERSPEED_PREFER_LOWEST, String.valueOf(false)); OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(config, null, null); - Position position = new Position(); - position.setTime(date("2017-01-01 00:00:00")); - position.setSpeed(50); DeviceState deviceState = new DeviceState(); - deviceState.setOverspeedState(false); - - Map events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId); - assertNull(events); - assertFalse(deviceState.getOverspeedState()); - assertEquals(position, deviceState.getOverspeedPosition()); - assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); - Position nextPosition = new Position(); - nextPosition.setTime(date("2017-01-01 00:00:10")); - nextPosition.setSpeed(55); + Position position = position("2017-01-01 00:00:00", 50); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + verifyState(deviceState, true, geofenceId); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); - assertNull(events); + position = position("2017-01-01 00:00:10", 55); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - nextPosition.setTime(date("2017-01-01 00:00:20")); - - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); + position = position("2017-01-01 00:00:20", 55); + var events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId); assertNotNull(events); Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); - assertEquals(50, event.getDouble("speed"), 0.1); + assertEquals(55, event.getDouble("speed"), 0.1); assertEquals(40, event.getDouble("speedLimit"), 0.1); assertEquals(geofenceId, event.getGeofenceId()); + verifyState(deviceState, true, 0); - assertEquals(notRepeat, deviceState.getOverspeedState()); - assertNull(deviceState.getOverspeedPosition()); - assertEquals(0, deviceState.getOverspeedGeofenceId()); - - nextPosition.setTime(date("2017-01-01 00:00:30")); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); - assertNull(events); - assertEquals(notRepeat, deviceState.getOverspeedState()); - - if (notRepeat) { - assertNull(deviceState.getOverspeedPosition()); - assertEquals(0, deviceState.getOverspeedGeofenceId()); - } else { - assertNotNull(deviceState.getOverspeedPosition()); - assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); - } - - nextPosition.setTime(date("2017-01-01 00:00:40")); - nextPosition.setSpeed(30); - - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); - assertNull(events); - assertFalse(deviceState.getOverspeedState()); - assertNull(deviceState.getOverspeedPosition()); - assertEquals(0, deviceState.getOverspeedGeofenceId()); - } - - private void testOverspeedWithStatus(boolean notRepeat) { - Config config = new Config(); - config.setString(Keys.EVENT_OVERSPEED_NOT_REPEAT, String.valueOf(notRepeat)); - config.setString(Keys.EVENT_OVERSPEED_MINIMAL_DURATION, String.valueOf(15)); - config.setString(Keys.EVENT_OVERSPEED_PREFER_LOWEST, String.valueOf(false)); - OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(config, null, null); + position = position("2017-01-01 00:00:30", 55); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + verifyState(deviceState, true, 0); - Position position = new Position(); - position.setTime(new Date(System.currentTimeMillis() - 30000)); - position.setSpeed(50); - DeviceState deviceState = new DeviceState(); - deviceState.setOverspeedState(false); - deviceState.setOverspeedPosition(position); - - Map events = overspeedEventHandler.updateOverspeedState(deviceState, 40); - - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); - assertEquals(notRepeat, deviceState.getOverspeedState()); + position = position("2017-01-01 00:00:30", 30); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + verifyState(deviceState, false, 0); } @Test public void testOverspeedEventHandler() throws Exception { - testOverspeedWithPosition(false, 0); - testOverspeedWithPosition(true, 0); - - testOverspeedWithPosition(false, 1); - testOverspeedWithPosition(true, 1); - - testOverspeedWithStatus(false); - testOverspeedWithStatus(true); + testOverspeedWithPosition(0); + testOverspeedWithPosition(1); } } -- cgit v1.2.3 From 388799edf2adc9c3070a83e72f074e523629574f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Sep 2022 17:53:50 -0700 Subject: Refactor motion handling --- .../traccar/handler/events/MotionEventHandler.java | 88 ++++++++--------- .../handler/events/OverspeedEventHandler.java | 2 +- .../org/traccar/reports/common/ReportUtils.java | 53 +++++----- src/main/java/org/traccar/session/DeviceState.java | 26 +++-- .../handler/events/MotionEventHandlerTest.java | 108 +++++++++------------ .../java/org/traccar/reports/ReportUtilsTest.java | 24 ++--- 6 files changed, 143 insertions(+), 158 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 7ef9ec21d..234899785 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -45,54 +45,52 @@ public class MotionEventHandler extends BaseEventHandler { this.tripsConfig = tripsConfig; } - private Map newEvent(DeviceState deviceState, boolean newMotion) { - String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - Position position = deviceState.getMotionPosition(); - Event event = new Event(eventType, position); - deviceState.setMotionState(newMotion); - deviceState.setMotionPosition(null); - return Collections.singletonMap(event, position); - } - - public Map updateMotionState(DeviceState deviceState, Position position) { - return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - } + public Map updateMotionState(DeviceState deviceState, Position position, boolean newState) { - public Map updateMotionState(DeviceState deviceState, Position position, boolean newMotion) { - Map result = null; - Boolean oldMotion = deviceState.getMotionState(); + boolean oldState = deviceState.getMotionState(); + if (oldState == newState) { + if (deviceState.getMotionTime() != null) { + long oldTime = deviceState.getMotionTime().getTime(); + long newTime = position.getFixTime().getTime(); - long currentTime = position.getFixTime().getTime(); - if (newMotion != oldMotion) { - if (deviceState.getMotionPosition() == null) { - deviceState.setMotionPosition(position); - } - } else { - deviceState.setMotionPosition(null); - } + double distance = position.getDouble(Position.KEY_TOTAL_DISTANCE) - deviceState.getMotionDistance(); + Boolean ignition = null; + if (tripsConfig.getUseIgnition() && position.hasAttribute(Position.KEY_IGNITION)) { + ignition = position.getBoolean(Position.KEY_IGNITION); + } - Position motionPosition = deviceState.getMotionPosition(); - if (motionPosition != null) { - long motionTime = motionPosition.getFixTime().getTime(); - double distance = PositionUtil.calculateDistance(motionPosition, position, false); - Boolean ignition = null; - if (tripsConfig.getUseIgnition() - && position.hasAttribute(Position.KEY_IGNITION)) { - ignition = position.getBoolean(Position.KEY_IGNITION); - } - if (newMotion) { - if (motionTime + tripsConfig.getMinimalTripDuration() <= currentTime - || distance >= tripsConfig.getMinimalTripDistance()) { - result = newEvent(deviceState, newMotion); + boolean generateEvent = false; + if (newState) { + if (newTime - oldTime >= tripsConfig.getMinimalTripDuration() + || distance >= tripsConfig.getMinimalTripDistance()) { + generateEvent = true; + } + } else { + if (newTime - oldTime >= tripsConfig.getMinimalParkingDuration() + || ignition != null && !ignition) { + generateEvent = true; + } } - } else { - if (motionTime + tripsConfig.getMinimalParkingDuration() <= currentTime - || ignition != null && !ignition) { - result = newEvent(deviceState, newMotion); + + if (generateEvent) { + + String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + Event event = new Event(eventType, position); + + deviceState.setMotionTime(null); + deviceState.setMotionDistance(0); + + return Collections.singletonMap(event, position); + } } + } else { + deviceState.setMotionState(newState); + deviceState.setMotionTime(position.getFixTime()); + deviceState.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); } - return result; + + return null; } @Override @@ -108,14 +106,8 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - Map result = null; DeviceState deviceState = connectionManager.getDeviceState(deviceId); - - if (deviceState.getMotionState() == null) { - deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); - } else { - result = updateMotionState(deviceState, position); - } + var result = updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index cfba56a38..3984299d7 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -136,7 +136,7 @@ public class OverspeedEventHandler extends BaseEventHandler { } DeviceState deviceState = connectionManager.getDeviceState(deviceId); - Map result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); + var result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 7fff46f66..2bca00df7 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -37,7 +37,6 @@ import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; -import org.traccar.model.Event; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.User; @@ -65,7 +64,6 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -353,38 +351,39 @@ public class ReportUtils { if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); MotionEventHandler motionHandler = new MotionEventHandler(null, null, tripsConfig); + DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); - int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; + + boolean detected = trips == deviceState.getMotionState(); + int startEventIndex = detected ? 0 : -1; int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { - Map event = motionHandler.updateMotionState(deviceState, positions.get(i), - isMoving(positions, i, tripsConfig)); - if (startEventIndex == -1 - && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips == deviceState.getMotionState() && event != null)) { - startEventIndex = i; - startNoEventIndex = -1; - } else if (trips != deviceState.getMotionState() && startEventIndex != -1 - && deviceState.getMotionPosition() == null && event == null) { - startEventIndex = -1; + boolean motion = isMoving(positions, i, tripsConfig); + if (deviceState.getMotionState() != motion) { + if (motion == trips) { + startEventIndex = detected ? startEventIndex : i; + startNoEventIndex = -1; + } else { + startNoEventIndex = i; + } } - if (startNoEventIndex == -1 - && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips != deviceState.getMotionState() && event != null)) { - startNoEventIndex = i; - } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { - startNoEventIndex = -1; - } - if (startEventIndex != -1 && startNoEventIndex != -1 && event != null - && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop( - device, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); - startEventIndex = -1; + + if (motionHandler.updateMotionState(deviceState, positions.get(i), motion) != null) { + if (motion == trips) { + detected = true; + startNoEventIndex = -1; + } else if (startEventIndex >= 0 && startNoEventIndex >= 0) { + result.add(calculateTripOrStop( + device, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + detected = false; + startEventIndex = -1; + startNoEventIndex = -1; + } } } - if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - int endIndex = startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1; + if (startEventIndex >= 0 && startEventIndex < positions.size() - 1) { + int endIndex = startNoEventIndex >= 0 ? startNoEventIndex : positions.size() - 1; result.add(calculateTripOrStop( device, positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); } diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java index f67b906c4..7bf2a62ac 100644 --- a/src/main/java/org/traccar/session/DeviceState.java +++ b/src/main/java/org/traccar/session/DeviceState.java @@ -16,30 +16,38 @@ */ package org.traccar.session; -import org.traccar.model.Position; - import java.util.Date; public class DeviceState { - private Boolean motionState; + private boolean motionState; public void setMotionState(boolean motionState) { this.motionState = motionState; } - public Boolean getMotionState() { + public boolean getMotionState() { return motionState; } - private Position motionPosition; + private Date motionTime; + + public Date getMotionTime() { + return motionTime; + } + + public void setMotionTime(Date motionTime) { + this.motionTime = motionTime; + } + + private double motionDistance; - public void setMotionPosition(Position motionPosition) { - this.motionPosition = motionPosition; + public double getMotionDistance() { + return motionDistance; } - public Position getMotionPosition() { - return motionPosition; + public void setMotionDistance(double motionDistance) { + this.motionDistance = motionDistance; } private boolean overspeedState; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 1f6212eec..0d4886429 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -10,89 +10,75 @@ import org.traccar.session.DeviceState; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; import java.util.TimeZone; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; public class MotionEventHandlerTest extends BaseTest { - private Date date(String time) throws ParseException { + private Position position(String time, boolean motion, double distance, Boolean ignition) throws ParseException { + Position position = new Position(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - return dateFormat.parse(time); + position.setTime(dateFormat.parse(time)); + position.set(Position.KEY_MOTION, motion); + position.set(Position.KEY_TOTAL_DISTANCE, distance); + position.set(Position.KEY_IGNITION, ignition); + return position; + } + + private void verifyState(DeviceState deviceState, boolean state, long distance) { + assertEquals(state, deviceState.getMotionState()); + assertEquals(distance, deviceState.getMotionDistance(), 0.1); } @Test - public void testMotionWithPosition() throws Exception { + public void testMotionWithPosition() throws ParseException { MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false, 0.01)); + null, null, new TripsConfig(500, 300000, 300000, 0, false, false, 0.01)); - Position position = new Position(); - position.setTime(date("2017-01-01 00:00:00")); - position.set(Position.KEY_MOTION, true); - position.set(Position.KEY_TOTAL_DISTANCE, 0); DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(false); - deviceState.setMotionPosition(position); - Position nextPosition = new Position(); - - nextPosition.setTime(date("2017-01-01 00:02:00")); - nextPosition.set(Position.KEY_MOTION, true); - nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - - Map events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNull(events); - - nextPosition.set(Position.KEY_TOTAL_DISTANCE, 600); - events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); - assertTrue(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); - - deviceState.setMotionState(false); - deviceState.setMotionPosition(position); - nextPosition.setTime(date("2017-01-01 00:06:00")); - nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(event); - event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); - assertTrue(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); + + Position position = position("2017-01-01 00:00:00", false, 0, null); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, false, 0); + + position = position("2017-01-01 00:02:00", true, 100, null); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, true, 100); + + position = position("2017-01-01 00:02:00", true, 700, null); + var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + assertEquals(Event.TYPE_DEVICE_MOVING, events.keySet().iterator().next().getType()); + verifyState(deviceState, true, 0); + + position = position("2017-01-01 00:03:00", false, 700, null); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, false, 700); + + position = position("2017-01-01 00:10:00", false, 700, null); + events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); + verifyState(deviceState, false, 0); } @Test - public void testStopWithPositionIgnition() throws Exception { + public void testStopWithPositionIgnition() throws ParseException { MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300 * 1000, 300 * 1000, 0, true, false, 0.01)); + null, null, new TripsConfig(500, 300000, 300000, 0, true, false, 0.01)); - Position position = new Position(); - position.setTime(date("2017-01-01 00:00:00")); - position.set(Position.KEY_MOTION, false); - position.set(Position.KEY_IGNITION, true); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(true); - deviceState.setMotionPosition(position); - - Position nextPosition = new Position(); - nextPosition.setTime(date("2017-01-01 00:02:00")); - nextPosition.set(Position.KEY_MOTION, false); - nextPosition.set(Position.KEY_IGNITION, false); - - Map events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_STOPPED, event.getType()); - assertFalse(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); + + Position position = position("2017-01-01 00:00:00", false, 100, true); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, false, 100); + + position = position("2017-01-01 00:02:00", false, 100, false); + var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); + verifyState(deviceState, false, 0); } } diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index aecb1c4a4..4bf668064 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -106,7 +106,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class), data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class), data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -120,7 +120,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -161,7 +161,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -189,7 +189,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -232,7 +232,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -246,7 +246,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -283,7 +283,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -312,7 +312,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -341,7 +341,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -370,7 +370,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -395,7 +395,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -409,7 +409,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 13b065fc4e8e1a4dc1f35312869151418fc660bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Sep 2022 21:03:04 -0700 Subject: Reformat forwarding request --- .../org/traccar/notification/EventForwarder.java | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index 279d5e678..50f17a852 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -68,18 +68,17 @@ public class EventForwarder { } LOGGER.debug("Event forwarding initiated"); - requestBuilder.async().post( - Entity.json(preparePayload(event, position)), new InvocationCallback() { - @Override - public void completed(Object o) { - LOGGER.debug("Event forwarding succeeded"); - } + requestBuilder.async().post(Entity.json(preparePayload(event, position)), new InvocationCallback<>() { + @Override + public void completed(Object o) { + LOGGER.debug("Event forwarding succeeded"); + } - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Event forwarding failed", throwable); - } - }); + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Event forwarding failed", throwable); + } + }); } protected Map preparePayload(Event event, Position position) { -- cgit v1.2.3 From abb26e80a5617424d960a0f7d0b98fcb379a5224 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Sep 2022 21:47:45 -0700 Subject: Fix forwarding date format --- src/main/java/org/traccar/MainModule.java | 9 +++-- .../helper/ObjectMapperContextResolver.java | 38 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/traccar/helper/ObjectMapperContextResolver.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index e0617a734..94669915b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -62,6 +62,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.helper.ObjectMapperContextResolver; import org.traccar.helper.SanitizerModule; import org.traccar.mail.LogMailManager; import org.traccar.mail.MailManager; @@ -81,7 +82,6 @@ import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.ext.ContextResolver; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -110,14 +110,13 @@ public class MainModule extends AbstractModule { objectMapper.registerModule(new SanitizerModule()); } objectMapper.registerModule(new JSR353Module()); - objectMapper.setConfig(objectMapper - .getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return objectMapper; } @Provides - public static Client provideClient(ObjectMapper objectMapper) { - return ClientBuilder.newClient().register((ContextResolver) clazz -> objectMapper); + public static Client provideClient(ObjectMapperContextResolver objectMapperContextResolver) { + return ClientBuilder.newClient().register(objectMapperContextResolver); } @Singleton diff --git a/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java b/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java new file mode 100644 index 000000000..b40e30d76 --- /dev/null +++ b/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java @@ -0,0 +1,38 @@ +/* + * 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.helper; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import javax.inject.Inject; +import javax.ws.rs.ext.ContextResolver; + +// This does not work as a lambda +public class ObjectMapperContextResolver implements ContextResolver { + + private final ObjectMapper objectMapper; + + @Inject + public ObjectMapperContextResolver(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public ObjectMapper getContext(Class clazz) { + return objectMapper; + } + +} -- cgit v1.2.3 From fe3d9995cceb2f1530a7c2549ae9a4cf457cb7f0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 25 Sep 2022 10:35:20 -0700 Subject: Persist device state --- schema/changelog-5.4.xml | 22 ++++++ schema/changelog-master.xml | 1 + .../traccar/handler/events/MotionEventHandler.java | 84 +++++++-------------- .../handler/events/OverspeedEventHandler.java | 80 +++++++------------- src/main/java/org/traccar/model/Device.java | 79 +++++++++++++++++++ .../org/traccar/reports/common/ReportUtils.java | 16 ++-- .../org/traccar/session/ConnectionManager.java | 10 --- src/main/java/org/traccar/session/DeviceState.java | 83 -------------------- .../org/traccar/session/state/MotionProcessor.java | 75 ++++++++++++++++++ .../org/traccar/session/state/MotionState.java | 88 ++++++++++++++++++++++ .../traccar/session/state/OverspeedProcessor.java | 65 ++++++++++++++++ .../org/traccar/session/state/OverspeedState.java | 88 ++++++++++++++++++++++ .../handler/events/MotionEventHandlerTest.java | 66 ++++++++-------- .../handler/events/OverspeedEventHandlerTest.java | 56 ++++++-------- 14 files changed, 537 insertions(+), 276 deletions(-) create mode 100644 schema/changelog-5.4.xml delete mode 100644 src/main/java/org/traccar/session/DeviceState.java create mode 100644 src/main/java/org/traccar/session/state/MotionProcessor.java create mode 100644 src/main/java/org/traccar/session/state/MotionState.java create mode 100644 src/main/java/org/traccar/session/state/OverspeedProcessor.java create mode 100644 src/main/java/org/traccar/session/state/OverspeedState.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.4.xml b/schema/changelog-5.4.xml new file mode 100644 index 000000000..f3a13ef59 --- /dev/null +++ b/schema/changelog-5.4.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index cea15397d..e877c1afd 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -34,5 +34,6 @@ + diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 234899785..0777f353a 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -17,14 +17,21 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; -import org.traccar.session.ConnectionManager; -import org.traccar.session.DeviceState; import org.traccar.session.cache.CacheManager; +import org.traccar.session.state.MotionProcessor; +import org.traccar.session.state.MotionState; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Collections; @@ -33,66 +40,20 @@ import java.util.Map; @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(MotionEventHandler.class); + private final CacheManager cacheManager; - private final ConnectionManager connectionManager; + private final Storage storage; private final TripsConfig tripsConfig; @Inject public MotionEventHandler( - CacheManager cacheManager, ConnectionManager connectionManager, TripsConfig tripsConfig) { + CacheManager cacheManager, Storage storage, TripsConfig tripsConfig) { this.cacheManager = cacheManager; - this.connectionManager = connectionManager; + this.storage = storage; this.tripsConfig = tripsConfig; } - public Map updateMotionState(DeviceState deviceState, Position position, boolean newState) { - - boolean oldState = deviceState.getMotionState(); - if (oldState == newState) { - if (deviceState.getMotionTime() != null) { - long oldTime = deviceState.getMotionTime().getTime(); - long newTime = position.getFixTime().getTime(); - - double distance = position.getDouble(Position.KEY_TOTAL_DISTANCE) - deviceState.getMotionDistance(); - Boolean ignition = null; - if (tripsConfig.getUseIgnition() && position.hasAttribute(Position.KEY_IGNITION)) { - ignition = position.getBoolean(Position.KEY_IGNITION); - } - - boolean generateEvent = false; - if (newState) { - if (newTime - oldTime >= tripsConfig.getMinimalTripDuration() - || distance >= tripsConfig.getMinimalTripDistance()) { - generateEvent = true; - } - } else { - if (newTime - oldTime >= tripsConfig.getMinimalParkingDuration() - || ignition != null && !ignition) { - generateEvent = true; - } - } - - if (generateEvent) { - - String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - Event event = new Event(eventType, position); - - deviceState.setMotionTime(null); - deviceState.setMotionDistance(0); - - return Collections.singletonMap(event, position); - - } - } - } else { - deviceState.setMotionState(newState); - deviceState.setMotionTime(position.getFixTime()); - deviceState.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - return null; - } - @Override protected Map analyzePosition(Position position) { @@ -106,10 +67,19 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - DeviceState deviceState = connectionManager.getDeviceState(deviceId); - var result = updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - connectionManager.setDeviceState(deviceId, deviceState); - return result; + MotionState state = MotionState.fromDevice(device); + MotionProcessor.updateState(state, position, position.getBoolean(Position.KEY_MOTION), tripsConfig); + if (state.isChanged()) { + state.toDevice(device); + try { + storage.updateObject(device, new Request( + new Columns.Include("motionState", "motionTime", "motionDistance"), + new Condition.Equals("id", "id"))); + } catch (StorageException e) { + LOGGER.warn("Update device motion error", e); + } + } + return state.getEvent() != null ? Collections.singletonMap(state.getEvent(), position) : null; } } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 3984299d7..c03b8eb7b 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -16,81 +16,50 @@ */ package org.traccar.handler.events; -import java.util.Collections; -import java.util.Map; - import io.netty.channel.ChannelHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.AttributeUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; -import org.traccar.session.ConnectionManager; -import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import org.traccar.session.state.OverspeedProcessor; +import org.traccar.session.state.OverspeedState; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; @ChannelHandler.Sharable public class OverspeedEventHandler extends BaseEventHandler { - public static final String ATTRIBUTE_SPEED = "speed"; + private static final Logger LOGGER = LoggerFactory.getLogger(OverspeedEventHandler.class); - private final ConnectionManager connectionManager; private final CacheManager cacheManager; + private final Storage storage; private final long minimalDuration; private final boolean preferLowest; @Inject - public OverspeedEventHandler(Config config, ConnectionManager connectionManager, CacheManager cacheManager) { - this.connectionManager = connectionManager; + public OverspeedEventHandler( + Config config, CacheManager cacheManager, Storage storage) { this.cacheManager = cacheManager; + this.storage = storage; minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); } - public Map updateOverspeedState( - DeviceState deviceState, Position position, double speedLimit, long geofenceId) { - - boolean oldState = deviceState.getOverspeedState(); - if (oldState) { - boolean newState = position.getSpeed() > speedLimit; - if (newState) { - if (deviceState.getOverspeedTime() != null) { - long oldTime = deviceState.getOverspeedTime().getTime(); - long newTime = position.getFixTime().getTime(); - if (newTime - oldTime > minimalDuration) { - - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); - event.set(ATTRIBUTE_SPEED, position.getSpeed()); - event.set(Position.KEY_SPEED_LIMIT, speedLimit); - event.setGeofenceId(deviceState.getOverspeedGeofenceId()); - - deviceState.setOverspeedTime(null); - deviceState.setOverspeedGeofenceId(0); - - return Collections.singletonMap(event, position); - - } - } - } else { - deviceState.setOverspeedState(false); - deviceState.setOverspeedTime(null); - deviceState.setOverspeedGeofenceId(0); - } - } else if (position != null && position.getSpeed() > speedLimit) { - deviceState.setOverspeedState(true); - deviceState.setOverspeedTime(position.getFixTime()); - deviceState.setOverspeedGeofenceId(geofenceId); - } - - return null; - } - @Override protected Map analyzePosition(Position position) { @@ -135,10 +104,19 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - DeviceState deviceState = connectionManager.getDeviceState(deviceId); - var result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); - connectionManager.setDeviceState(deviceId, deviceState); - return result; + OverspeedState state = OverspeedState.fromDevice(device); + OverspeedProcessor.updateState(state, position, speedLimit, minimalDuration, overspeedGeofenceId); + if (state.isChanged()) { + state.toDevice(device); + try { + storage.updateObject(device, new Request( + new Columns.Include("overspeedState", "overspeedTime", "overspeedGeofenceId"), + new Condition.Equals("id", "id"))); + } catch (StorageException e) { + LOGGER.warn("Update device overspeed error", e); + } + } + return state.getEvent() != null ? Collections.singletonMap(state.getEvent(), position) : null; } } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index f21e5ca84..147b0fd20 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -19,6 +19,7 @@ import java.util.Date; import java.util.List; import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -162,4 +163,82 @@ public class Device extends GroupedModel implements Disableable { this.expirationTime = expirationTime; } + private boolean motionState; + + @QueryIgnore + @JsonIgnore + public boolean getMotionState() { + return motionState; + } + + @JsonIgnore + public void setMotionState(boolean motionState) { + this.motionState = motionState; + } + + private Date motionTime; + + @QueryIgnore + @JsonIgnore + public Date getMotionTime() { + return motionTime; + } + + @JsonIgnore + public void setMotionTime(Date motionTime) { + this.motionTime = motionTime; + } + + private double motionDistance; + + @QueryIgnore + @JsonIgnore + public double getMotionDistance() { + return motionDistance; + } + + @JsonIgnore + public void setMotionDistance(double motionDistance) { + this.motionDistance = motionDistance; + } + + private boolean overspeedState; + + @QueryIgnore + @JsonIgnore + public boolean getOverspeedState() { + return overspeedState; + } + + @JsonIgnore + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + } + + private Date overspeedTime; + + @QueryIgnore + @JsonIgnore + public Date getOverspeedTime() { + return overspeedTime; + } + + @JsonIgnore + public void setOverspeedTime(Date overspeedTime) { + this.overspeedTime = overspeedTime; + } + + private long overspeedGeofenceId; + + @QueryIgnore + @JsonIgnore + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + + @JsonIgnore + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + } + } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 2bca00df7..57ed4d148 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -30,7 +30,6 @@ import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.geocoder.Geocoder; -import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; @@ -43,7 +42,8 @@ import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.session.DeviceState; +import org.traccar.session.state.MotionProcessor; +import org.traccar.session.state.MotionState; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -350,17 +350,16 @@ public class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(null, null, tripsConfig); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); + MotionState motionState = new MotionState(); + motionState.setMotionState(isMoving(positions, 0, tripsConfig)); - boolean detected = trips == deviceState.getMotionState(); + boolean detected = trips == motionState.getMotionState(); int startEventIndex = detected ? 0 : -1; int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { boolean motion = isMoving(positions, i, tripsConfig); - if (deviceState.getMotionState() != motion) { + if (motionState.getMotionState() != motion) { if (motion == trips) { startEventIndex = detected ? startEventIndex : i; startNoEventIndex = -1; @@ -369,7 +368,8 @@ public class ReportUtils { } } - if (motionHandler.updateMotionState(deviceState, positions.get(i), motion) != null) { + MotionProcessor.updateState(motionState, positions.get(i), motion, tripsConfig); + if (motionState.getEvent() != null) { if (motion == trips) { detected = true; startNoEventIndex = -1; diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index c826b99db..9e50c9ead 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -66,8 +66,6 @@ public class ConnectionManager implements BroadcastInterface { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); - private final Map deviceStates = new ConcurrentHashMap<>(); - private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -275,14 +273,6 @@ public class ConnectionManager implements BroadcastInterface { updateDevice(true, device); } - public DeviceState getDeviceState(long deviceId) { - return deviceStates.computeIfAbsent(deviceId, x -> new DeviceState()); - } - - public void setDeviceState(long deviceId, DeviceState deviceState) { - deviceStates.put(deviceId, deviceState); - } - public synchronized void sendKeepalive() { for (Set userListeners : listeners.values()) { for (UpdateListener listener : userListeners) { diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java deleted file mode 100644 index 7bf2a62ac..000000000 --- a/src/main/java/org/traccar/session/DeviceState.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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"); - * 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.session; - -import java.util.Date; - -public class DeviceState { - - private boolean motionState; - - public void setMotionState(boolean motionState) { - this.motionState = motionState; - } - - public boolean getMotionState() { - return motionState; - } - - private Date motionTime; - - public Date getMotionTime() { - return motionTime; - } - - public void setMotionTime(Date motionTime) { - this.motionTime = motionTime; - } - - private double motionDistance; - - public double getMotionDistance() { - return motionDistance; - } - - public void setMotionDistance(double motionDistance) { - this.motionDistance = motionDistance; - } - - private boolean overspeedState; - - public void setOverspeedState(boolean overspeedState) { - this.overspeedState = overspeedState; - } - - public boolean getOverspeedState() { - return overspeedState; - } - - private Date overspeedTime; - - public Date getOverspeedTime() { - return overspeedTime; - } - - public void setOverspeedTime(Date overspeedTime) { - this.overspeedTime = overspeedTime; - } - - private long overspeedGeofenceId; - - public void setOverspeedGeofenceId(long overspeedGeofenceId) { - this.overspeedGeofenceId = overspeedGeofenceId; - } - - public long getOverspeedGeofenceId() { - return overspeedGeofenceId; - } - -} diff --git a/src/main/java/org/traccar/session/state/MotionProcessor.java b/src/main/java/org/traccar/session/state/MotionProcessor.java new file mode 100644 index 000000000..b9d706492 --- /dev/null +++ b/src/main/java/org/traccar/session/state/MotionProcessor.java @@ -0,0 +1,75 @@ +/* + * 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.session.state; + +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.reports.common.TripsConfig; + +public final class MotionProcessor { + + private MotionProcessor() { + } + + public static void updateState( + MotionState state, Position position, boolean newState, TripsConfig tripsConfig) { + + state.setEvent(null); + + boolean oldState = state.getMotionState(); + if (oldState == newState) { + if (state.getMotionTime() != null) { + long oldTime = state.getMotionTime().getTime(); + long newTime = position.getFixTime().getTime(); + + double distance = position.getDouble(Position.KEY_TOTAL_DISTANCE) - state.getMotionDistance(); + Boolean ignition = null; + if (tripsConfig.getUseIgnition() && position.hasAttribute(Position.KEY_IGNITION)) { + ignition = position.getBoolean(Position.KEY_IGNITION); + } + + boolean generateEvent = false; + if (newState) { + if (newTime - oldTime >= tripsConfig.getMinimalTripDuration() + || distance >= tripsConfig.getMinimalTripDistance()) { + generateEvent = true; + } + } else { + if (newTime - oldTime >= tripsConfig.getMinimalParkingDuration() + || ignition != null && !ignition) { + generateEvent = true; + } + } + + if (generateEvent) { + + String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + Event event = new Event(eventType, position); + + state.setMotionTime(null); + state.setMotionDistance(0); + state.setEvent(event); + + } + } + } else { + state.setMotionState(newState); + state.setMotionTime(position.getFixTime()); + state.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + } + +} diff --git a/src/main/java/org/traccar/session/state/MotionState.java b/src/main/java/org/traccar/session/state/MotionState.java new file mode 100644 index 000000000..e3ce58ab2 --- /dev/null +++ b/src/main/java/org/traccar/session/state/MotionState.java @@ -0,0 +1,88 @@ +/* + * 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.session.state; + +import org.traccar.model.Device; +import org.traccar.model.Event; + +import java.util.Date; + +public class MotionState { + + public static MotionState fromDevice(Device device) { + MotionState state = new MotionState(); + state.motionState = device.getMotionState(); + state.motionTime = device.getMotionTime(); + state.motionDistance = device.getMotionDistance(); + return state; + } + + public void toDevice(Device device) { + device.setMotionState(motionState); + device.setMotionTime(motionTime); + device.setMotionDistance(motionDistance); + } + + private boolean changed; + + public boolean isChanged() { + return changed; + } + + private boolean motionState; + + public boolean getMotionState() { + return motionState; + } + + public void setMotionState(boolean motionState) { + this.motionState = motionState; + changed = true; + } + + private Date motionTime; + + public Date getMotionTime() { + return motionTime; + } + + public void setMotionTime(Date motionTime) { + this.motionTime = motionTime; + changed = true; + } + + private double motionDistance; + + public double getMotionDistance() { + return motionDistance; + } + + public void setMotionDistance(double motionDistance) { + this.motionDistance = motionDistance; + changed = true; + } + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + +} diff --git a/src/main/java/org/traccar/session/state/OverspeedProcessor.java b/src/main/java/org/traccar/session/state/OverspeedProcessor.java new file mode 100644 index 000000000..62f6a3de2 --- /dev/null +++ b/src/main/java/org/traccar/session/state/OverspeedProcessor.java @@ -0,0 +1,65 @@ +/* + * 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.session.state; + +import org.traccar.model.Event; +import org.traccar.model.Position; + +public final class OverspeedProcessor { + + public static final String ATTRIBUTE_SPEED = "speed"; + + private OverspeedProcessor() { + } + + public static void updateState( + OverspeedState state, Position position, double speedLimit, long minimalDuration, long geofenceId) { + + state.setEvent(null); + + boolean oldState = state.getOverspeedState(); + if (oldState) { + boolean newState = position.getSpeed() > speedLimit; + if (newState) { + if (state.getOverspeedTime() != null) { + long oldTime = state.getOverspeedTime().getTime(); + long newTime = position.getFixTime().getTime(); + if (newTime - oldTime > minimalDuration) { + + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); + event.set(ATTRIBUTE_SPEED, position.getSpeed()); + event.set(Position.KEY_SPEED_LIMIT, speedLimit); + event.setGeofenceId(state.getOverspeedGeofenceId()); + + state.setOverspeedTime(null); + state.setOverspeedGeofenceId(0); + state.setEvent(event); + + } + } + } else { + state.setOverspeedState(false); + state.setOverspeedTime(null); + state.setOverspeedGeofenceId(0); + } + } else if (position != null && position.getSpeed() > speedLimit) { + state.setOverspeedState(true); + state.setOverspeedTime(position.getFixTime()); + state.setOverspeedGeofenceId(geofenceId); + } + } + +} diff --git a/src/main/java/org/traccar/session/state/OverspeedState.java b/src/main/java/org/traccar/session/state/OverspeedState.java new file mode 100644 index 000000000..340ede6d7 --- /dev/null +++ b/src/main/java/org/traccar/session/state/OverspeedState.java @@ -0,0 +1,88 @@ +/* + * 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.session.state; + +import org.traccar.model.Device; +import org.traccar.model.Event; + +import java.util.Date; + +public class OverspeedState { + + public static OverspeedState fromDevice(Device device) { + OverspeedState state = new OverspeedState(); + state.overspeedState = device.getOverspeedState(); + state.overspeedTime = device.getOverspeedTime(); + state.overspeedGeofenceId = device.getOverspeedGeofenceId(); + return state; + } + + public void toDevice(Device device) { + device.setOverspeedState(overspeedState); + device.setOverspeedTime(overspeedTime); + device.setOverspeedGeofenceId(overspeedGeofenceId); + } + + private boolean changed; + + public boolean isChanged() { + return changed; + } + + private boolean overspeedState; + + public boolean getOverspeedState() { + return overspeedState; + } + + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + changed = true; + } + + private Date overspeedTime; + + public Date getOverspeedTime() { + return overspeedTime; + } + + public void setOverspeedTime(Date overspeedTime) { + this.overspeedTime = overspeedTime; + changed = true; + } + + private long overspeedGeofenceId; + + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + changed = true; + } + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + +} diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 0d4886429..22afbfa52 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -5,7 +5,8 @@ import org.traccar.BaseTest; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; -import org.traccar.session.DeviceState; +import org.traccar.session.state.MotionProcessor; +import org.traccar.session.state.MotionState; import java.text.DateFormat; import java.text.ParseException; @@ -28,57 +29,52 @@ public class MotionEventHandlerTest extends BaseTest { return position; } - private void verifyState(DeviceState deviceState, boolean state, long distance) { - assertEquals(state, deviceState.getMotionState()); - assertEquals(distance, deviceState.getMotionDistance(), 0.1); + private void verifyState(MotionState motionState, boolean state, long distance) { + assertEquals(state, motionState.getMotionState()); + assertEquals(distance, motionState.getMotionDistance(), 0.1); } @Test public void testMotionWithPosition() throws ParseException { - MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300000, 300000, 0, false, false, 0.01)); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false, 0.01); - DeviceState deviceState = new DeviceState(); + MotionState state = new MotionState(); - Position position = position("2017-01-01 00:00:00", false, 0, null); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, false, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:00:00", false, 0, null), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 0); - position = position("2017-01-01 00:02:00", true, 100, null); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, true, 100); + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", true, 100, null), true, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, true, 100); - position = position("2017-01-01 00:02:00", true, 700, null); - var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - assertEquals(Event.TYPE_DEVICE_MOVING, events.keySet().iterator().next().getType()); - verifyState(deviceState, true, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", true, 700, null), true, tripsConfig); + assertEquals(Event.TYPE_DEVICE_MOVING, state.getEvent().getType()); + verifyState(state, true, 0); - position = position("2017-01-01 00:03:00", false, 700, null); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, false, 700); + MotionProcessor.updateState(state, position("2017-01-01 00:03:00", false, 700, null), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 700); - position = position("2017-01-01 00:10:00", false, 700, null); - events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); - verifyState(deviceState, false, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:10:00", false, 700, null), false, tripsConfig); + assertEquals(Event.TYPE_DEVICE_STOPPED, state.getEvent().getType()); + verifyState(state, false, 0); } @Test public void testStopWithPositionIgnition() throws ParseException { - MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300000, 300000, 0, true, false, 0.01)); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false, 0.01); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(true); + MotionState state = new MotionState(); + state.setMotionState(true); - Position position = position("2017-01-01 00:00:00", false, 100, true); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, false, 100); + MotionProcessor.updateState(state, position("2017-01-01 00:00:00", false, 100, true), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 100); - position = position("2017-01-01 00:02:00", false, 100, false); - var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); - verifyState(deviceState, false, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", false, 100, false), false, tripsConfig); + assertEquals(Event.TYPE_DEVICE_STOPPED, state.getEvent().getType()); + verifyState(state, false, 0); } } diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index bbddbae72..ee18ee052 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -2,11 +2,10 @@ package org.traccar.handler.events; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.session.DeviceState; +import org.traccar.session.state.OverspeedProcessor; +import org.traccar.session.state.OverspeedState; import java.text.DateFormat; import java.text.ParseException; @@ -28,43 +27,36 @@ public class OverspeedEventHandlerTest extends BaseTest { return position; } - private void verifyState(DeviceState deviceState, boolean state, long geofenceId) { - assertEquals(state, deviceState.getOverspeedState()); - assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); + private void verifyState(OverspeedState overspeedState, boolean state, long geofenceId) { + assertEquals(state, overspeedState.getOverspeedState()); + assertEquals(geofenceId, overspeedState.getOverspeedGeofenceId()); } private void testOverspeedWithPosition(long geofenceId) throws ParseException { - Config config = new Config(); - config.setString(Keys.EVENT_OVERSPEED_MINIMAL_DURATION, String.valueOf(15)); - config.setString(Keys.EVENT_OVERSPEED_PREFER_LOWEST, String.valueOf(false)); - OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(config, null, null); + OverspeedState state = new OverspeedState(); - DeviceState deviceState = new DeviceState(); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:00", 50), 40, 15000, geofenceId); + assertNull(state.getEvent()); + verifyState(state, true, geofenceId); - Position position = position("2017-01-01 00:00:00", 50); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - verifyState(deviceState, true, geofenceId); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:10", 55), 40, 15000, geofenceId); + assertNull(state.getEvent()); - position = position("2017-01-01 00:00:10", 55); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:20", 55), 40, 15000, geofenceId); + assertNotNull(state.getEvent()); + assertEquals(Event.TYPE_DEVICE_OVERSPEED, state.getEvent().getType()); + assertEquals(55, state.getEvent().getDouble("speed"), 0.1); + assertEquals(40, state.getEvent().getDouble("speedLimit"), 0.1); + assertEquals(geofenceId, state.getEvent().getGeofenceId()); + verifyState(state, true, 0); - position = position("2017-01-01 00:00:20", 55); - var events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId); - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); - assertEquals(55, event.getDouble("speed"), 0.1); - assertEquals(40, event.getDouble("speedLimit"), 0.1); - assertEquals(geofenceId, event.getGeofenceId()); - verifyState(deviceState, true, 0); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 55), 40, 15000, geofenceId); + assertNull(state.getEvent()); + verifyState(state, true, 0); - position = position("2017-01-01 00:00:30", 55); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - verifyState(deviceState, true, 0); - - position = position("2017-01-01 00:00:30", 30); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - verifyState(deviceState, false, 0); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 30), 40, 15000, geofenceId); + assertNull(state.getEvent()); + verifyState(state, false, 0); } @Test -- cgit v1.2.3 From 706de3e02cde8daa0bce29dd2ff96703f17ff92a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Sep 2022 08:37:44 -0700 Subject: Better PID decoding error --- src/main/java/org/traccar/protocol/CastelProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index c2b740c4c..4aa65245b 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -160,6 +160,9 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < count; i++) { int value; + if (!PID_LENGTH_MAP.containsKey(pids[i])) { + throw new RuntimeException(String.format("Unknown PID 0x%02x", pids[i])); + } switch (PID_LENGTH_MAP.get(pids[i])) { case 1: value = buf.readUnsignedByte(); -- 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 'src/main/java/org') 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 257ee673e08d2d4080d156079ce7b62752f1476d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 28 Sep 2022 07:13:11 -0700 Subject: Queued command model --- src/main/java/org/traccar/model/BaseCommand.java | 40 +++++++++++++++++++ src/main/java/org/traccar/model/Command.java | 29 +------------- src/main/java/org/traccar/model/QueuedCommand.java | 45 ++++++++++++++++++++++ 3 files changed, 87 insertions(+), 27 deletions(-) create mode 100644 src/main/java/org/traccar/model/BaseCommand.java create mode 100644 src/main/java/org/traccar/model/QueuedCommand.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/BaseCommand.java b/src/main/java/org/traccar/model/BaseCommand.java new file mode 100644 index 000000000..16df9c126 --- /dev/null +++ b/src/main/java/org/traccar/model/BaseCommand.java @@ -0,0 +1,40 @@ +/* + * 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.model; + +public class BaseCommand extends Message { + + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + private boolean textChannel; + + public boolean getTextChannel() { + return textChannel; + } + + public void setTextChannel(boolean textChannel) { + this.textChannel = textChannel; + } + +} diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 49486bdbc..4ea619e95 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.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. @@ -22,7 +22,7 @@ import org.traccar.storage.StorageName; @StorageName("tc_commands") @JsonIgnoreProperties(ignoreUnknown = true) -public class Command extends Message implements Cloneable { +public class Command extends BaseCommand { public static final String TYPE_CUSTOM = "custom"; public static final String TYPE_IDENTIFICATION = "deviceIdentification"; @@ -84,21 +84,6 @@ public class Command extends Message implements Cloneable { public static final String KEY_SERVER = "server"; public static final String KEY_PORT = "port"; - @Override - public Command clone() throws CloneNotSupportedException { - return (Command) super.clone(); - } - - private boolean textChannel; - - public boolean getTextChannel() { - return textChannel; - } - - public void setTextChannel(boolean textChannel) { - this.textChannel = textChannel; - } - @QueryIgnore @Override public long getDeviceId() { @@ -111,14 +96,4 @@ public class Command extends Message implements Cloneable { super.setDeviceId(deviceId); } - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - } diff --git a/src/main/java/org/traccar/model/QueuedCommand.java b/src/main/java/org/traccar/model/QueuedCommand.java new file mode 100644 index 000000000..fff77a22b --- /dev/null +++ b/src/main/java/org/traccar/model/QueuedCommand.java @@ -0,0 +1,45 @@ +/* + * 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.model; + +import org.traccar.storage.StorageName; + +import java.util.HashMap; + +@StorageName("tc_commands_queue") +public class QueuedCommand extends BaseCommand { + + public static QueuedCommand fromCommand(Command command) { + QueuedCommand queuedCommand = new QueuedCommand(); + queuedCommand.setDeviceId(command.getDeviceId()); + queuedCommand.setType(command.getType()); + queuedCommand.setDescription(command.getDescription()); + queuedCommand.setTextChannel(command.getTextChannel()); + queuedCommand.setAttributes(new HashMap<>(command.getAttributes())); + return queuedCommand; + } + + public Command toCommand() { + Command command = new Command(); + command.setDeviceId(getDeviceId()); + command.setType(getType()); + command.setDescription(getDescription()); + command.setTextChannel(getTextChannel()); + command.setAttributes(new HashMap<>(getAttributes())); + return command; + } + +} -- cgit v1.2.3 From 0f74a9c4452a044ff619f0b24d69b41aece09b94 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:17:42 -0700 Subject: Remove queueing parameter --- src/main/java/org/traccar/config/Keys.java | 8 -------- src/main/java/org/traccar/database/CommandsManager.java | 12 ++++-------- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ea394d914..1da01518c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -779,14 +779,6 @@ public final class Keys { "event.forward.header", List.of(KeyType.CONFIG)); - /** - * Enable commands queuing when devices are offline. Commands are buffered in memory only, so restarting service - * will clear the buffer. - */ - public static final ConfigKey COMMANDS_QUEUEING = new BooleanConfigKey( - "commands.queueing", - List.of(KeyType.CONFIG)); - /** * Root folder for all template files. */ diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 2967b8abd..49eda79b2 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -18,8 +18,6 @@ package org.traccar.database; import org.traccar.BaseProtocol; import org.traccar.ServerManager; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; @@ -55,22 +53,22 @@ public class CommandsManager { private final SmsManager smsManager; private final ConnectionManager connectionManager; - private final boolean queueing; - @Inject public CommandsManager( Storage storage, ServerManager serverManager, @Nullable SmsManager smsManager, - ConnectionManager connectionManager, Config config) { + ConnectionManager connectionManager) { this.storage = storage; this.serverManager = serverManager; this.smsManager = smsManager; this.connectionManager = connectionManager; - queueing = config.getBoolean(Keys.COMMANDS_QUEUEING); } public boolean sendCommand(Command command) throws Exception { long deviceId = command.getDeviceId(); if (command.getTextChannel()) { + if (smsManager == null) { + throw new RuntimeException("SMS not configured"); + } Device device = storage.getObject(Device.class, new Request( new Columns.Include("positionId", "phone"), new Condition.Equals("id", "id", deviceId))); Position position = storage.getObject(Position.class, new Request( @@ -92,8 +90,6 @@ public class CommandsManager { getDeviceQueue(deviceId).add(command); return false; } - } else if (!queueing) { - throw new RuntimeException("Device is not online"); } else { getDeviceQueue(deviceId).add(command); return false; -- cgit v1.2.3 From 7246644f393f9a373f4e3f2be846500e8456a286 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:23:16 -0700 Subject: Simplify commands logic --- src/main/java/org/traccar/database/CommandsManager.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 49eda79b2..945fb13af 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -83,13 +83,8 @@ public class CommandsManager { } } else { DeviceSession deviceSession = connectionManager.getDeviceSession(deviceId); - if (deviceSession != null) { - if (deviceSession.supportsLiveCommands()) { - deviceSession.sendCommand(command); - } else { - getDeviceQueue(deviceId).add(command); - return false; - } + if (deviceSession != null && deviceSession.supportsLiveCommands()) { + deviceSession.sendCommand(command); } else { getDeviceQueue(deviceId).add(command); return false; -- cgit v1.2.3 From e7bd758824386e4f77f78ceca57675ef7934435a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:43:30 -0700 Subject: Use DB command queue --- .../java/org/traccar/database/CommandsManager.java | 62 ++++++---------------- 1 file changed, 17 insertions(+), 45 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 945fb13af..d56b4d472 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -21,33 +21,27 @@ import org.traccar.ServerManager; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.model.QueuedCommand; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import org.traccar.sms.SmsManager; import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Limit; +import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.ArrayList; import java.util.Collection; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; @Singleton public class CommandsManager { - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final Map> deviceQueues = new ConcurrentHashMap<>(); - private final Storage storage; private final ServerManager serverManager; private final SmsManager smsManager; @@ -86,54 +80,32 @@ public class CommandsManager { if (deviceSession != null && deviceSession.supportsLiveCommands()) { deviceSession.sendCommand(command); } else { - getDeviceQueue(deviceId).add(command); + storage.addObject(QueuedCommand.fromCommand(command), new Request(new Columns.Exclude("id"))); return false; } } return true; } - private Queue getDeviceQueue(long deviceId) { - Queue deviceQueue; - try { - lock.readLock().lock(); - deviceQueue = deviceQueues.get(deviceId); - } finally { - lock.readLock().unlock(); - } - if (deviceQueue != null) { - return deviceQueue; - } else { - try { - lock.writeLock().lock(); - return deviceQueues.computeIfAbsent(deviceId, key -> new ConcurrentLinkedQueue<>()); - } finally { - lock.writeLock().unlock(); - } - } - } - public Collection readQueuedCommands(long deviceId) { return readQueuedCommands(deviceId, Integer.MAX_VALUE); } public Collection readQueuedCommands(long deviceId, int count) { - Queue deviceQueue; try { - lock.readLock().lock(); - deviceQueue = deviceQueues.get(deviceId); - } finally { - lock.readLock().unlock(); - } - Collection result = new ArrayList<>(); - if (deviceQueue != null) { - Command command = deviceQueue.poll(); - while (command != null && result.size() < count) { - result.add(command); - command = deviceQueue.poll(); + var commands = storage.getObjects(QueuedCommand.class, new Request( + new Columns.All(), + new Condition.Equals("deviceId", "deviceId", deviceId), + new Order(false, "id"), + new Limit(count))); + for (var command : commands) { + storage.removeObject(QueuedCommand.class, new Request( + new Condition.Equals("id", "id", command.getId()))); } + return commands.stream().map(QueuedCommand::toCommand).collect(Collectors.toList()); + } catch (StorageException e) { + throw new RuntimeException(e); } - return result; } } -- cgit v1.2.3 From 0a853f2aa3556554acd0b43a5008c43c345fa300 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:57:22 -0700 Subject: Synchronize queued commands --- .../org/traccar/broadcast/BroadcastInterface.java | 3 +++ .../org/traccar/broadcast/BroadcastMessage.java | 10 ++++++++++ .../broadcast/MulticastBroadcastService.java | 9 +++++++++ .../java/org/traccar/database/CommandsManager.java | 22 ++++++++++++++++++++-- 4 files changed, 42 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java index dddba68b6..673ebd8b8 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastInterface.java +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -31,6 +31,9 @@ public interface BroadcastInterface { default void updateEvent(boolean local, long userId, Event event) { } + default void updateCommand(boolean local, long deviceId) { + } + default void invalidateObject(boolean local, Class clazz, long id) { } diff --git a/src/main/java/org/traccar/broadcast/BroadcastMessage.java b/src/main/java/org/traccar/broadcast/BroadcastMessage.java index 3e22be7e0..985848d04 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastMessage.java +++ b/src/main/java/org/traccar/broadcast/BroadcastMessage.java @@ -63,6 +63,16 @@ public class BroadcastMessage { this.event = event; } + private Long commandDeviceId; + + public Long getCommandDeviceId() { + return commandDeviceId; + } + + public void setCommandDeviceId(Long commandDeviceId) { + this.commandDeviceId = commandDeviceId; + } + private Map changes; public Map getChanges() { diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index be65b7826..b1b66f1e3 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -102,6 +102,13 @@ public class MulticastBroadcastService implements BroadcastService { sendMessage(message); } + @Override + public void updateCommand(boolean local, long deviceId) { + BroadcastMessage message = new BroadcastMessage(); + message.setCommandDeviceId(deviceId); + sendMessage(message); + } + @Override public void invalidateObject(boolean local, Class clazz, long id) { BroadcastMessage message = new BroadcastMessage(); @@ -136,6 +143,8 @@ public class MulticastBroadcastService implements BroadcastService { listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); } else if (message.getUserId() != null && message.getEvent() != null) { listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); + } else if (message.getCommandDeviceId() != null) { + listeners.forEach(listener -> listener.updateCommand(false, message.getCommandDeviceId())); } else if (message.getChanges() != null) { var iterator = message.getChanges().entrySet().iterator(); if (iterator.hasNext()) { diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index d56b4d472..53040ad53 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -18,6 +18,8 @@ package org.traccar.database; import org.traccar.BaseProtocol; import org.traccar.ServerManager; +import org.traccar.broadcast.BroadcastInterface; +import org.traccar.broadcast.BroadcastService; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; @@ -40,21 +42,24 @@ import java.util.Collection; import java.util.stream.Collectors; @Singleton -public class CommandsManager { +public class CommandsManager implements BroadcastInterface { private final Storage storage; private final ServerManager serverManager; private final SmsManager smsManager; private final ConnectionManager connectionManager; + private final BroadcastService broadcastService; @Inject public CommandsManager( Storage storage, ServerManager serverManager, @Nullable SmsManager smsManager, - ConnectionManager connectionManager) { + ConnectionManager connectionManager, BroadcastService broadcastService) { this.storage = storage; this.serverManager = serverManager; this.smsManager = smsManager; this.connectionManager = connectionManager; + this.broadcastService = broadcastService; + broadcastService.registerListener(this); } public boolean sendCommand(Command command) throws Exception { @@ -81,6 +86,7 @@ public class CommandsManager { deviceSession.sendCommand(command); } else { storage.addObject(QueuedCommand.fromCommand(command), new Request(new Columns.Exclude("id"))); + broadcastService.updateCommand(true, deviceId); return false; } } @@ -108,4 +114,16 @@ public class CommandsManager { } } + @Override + public void updateCommand(boolean local, long deviceId) { + if (!local) { + DeviceSession deviceSession = connectionManager.getDeviceSession(deviceId); + if (deviceSession != null && deviceSession.supportsLiveCommands()) { + for (Command command : readQueuedCommands(deviceId)) { + deviceSession.sendCommand(command); + } + } + } + } + } -- cgit v1.2.3 From 63a8bb747e92cc98d64bad59464922a9f6be5867 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 1 Oct 2022 19:24:15 -0700 Subject: Enable iOS sound --- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 3723a4226..5ce2cbc0b 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -21,6 +21,8 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.AndroidConfig; import com.google.firebase.messaging.AndroidNotification; +import com.google.firebase.messaging.ApnsConfig; +import com.google.firebase.messaging.Aps; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; import com.google.firebase.messaging.MulticastMessage; @@ -79,6 +81,11 @@ public class NotificatorFirebase implements Notificator { .setSound("default") .build()) .build()) + .setApnsConfig(ApnsConfig.builder() + .setAps(Aps.builder() + .setSound("default") + .build()) + .build()) .addAllTokens(registrationTokens) .putData("eventId", String.valueOf(event.getId())) .build(); -- cgit v1.2.3 From ae3eddba7e0a6688807f71d2c290618d1c49da05 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 08:39:06 -0700 Subject: Use singletons where possible --- src/main/java/org/traccar/MainEventHandler.java | 9 +++++---- src/main/java/org/traccar/MainModule.java | 9 ++++++++- src/main/java/org/traccar/WebDataHandler.java | 2 ++ src/main/java/org/traccar/api/CorsResponseFilter.java | 2 ++ src/main/java/org/traccar/api/security/LoginService.java | 2 ++ src/main/java/org/traccar/api/signature/CryptoManager.java | 2 ++ src/main/java/org/traccar/api/signature/TokenManager.java | 2 ++ src/main/java/org/traccar/database/MediaManager.java | 2 ++ src/main/java/org/traccar/database/NotificationManager.java | 2 ++ src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 2 ++ src/main/java/org/traccar/handler/CopyAttributesHandler.java | 2 ++ src/main/java/org/traccar/handler/DefaultDataHandler.java | 2 ++ src/main/java/org/traccar/handler/DistanceHandler.java | 2 ++ src/main/java/org/traccar/handler/EngineHoursHandler.java | 2 ++ src/main/java/org/traccar/handler/FilterHandler.java | 2 ++ src/main/java/org/traccar/handler/HemisphereHandler.java | 2 ++ src/main/java/org/traccar/handler/MotionHandler.java | 2 ++ src/main/java/org/traccar/handler/RemoteAddressHandler.java | 2 ++ src/main/java/org/traccar/handler/SpeedLimitHandler.java | 2 ++ src/main/java/org/traccar/handler/TimeHandler.java | 2 ++ src/main/java/org/traccar/handler/events/AlertEventHandler.java | 2 ++ .../java/org/traccar/handler/events/BehaviorEventHandler.java | 2 ++ .../org/traccar/handler/events/CommandResultEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/DriverEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/FuelEventHandler.java | 2 ++ .../java/org/traccar/handler/events/GeofenceEventHandler.java | 2 ++ .../java/org/traccar/handler/events/IgnitionEventHandler.java | 2 ++ .../java/org/traccar/handler/events/MaintenanceEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/MediaEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/MotionEventHandler.java | 2 ++ .../java/org/traccar/handler/events/OverspeedEventHandler.java | 2 ++ .../java/org/traccar/notification/NotificationFormatter.java | 2 ++ .../java/org/traccar/notification/TextTemplateFormatter.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorMail.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorPushover.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorSms.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorTelegram.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorTraccar.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorWeb.java | 8 +++----- src/main/java/org/traccar/reports/common/ReportUtils.java | 2 ++ src/main/java/org/traccar/reports/common/TripsConfig.java | 2 ++ src/main/java/org/traccar/web/WebServer.java | 2 -- 42 files changed, 92 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 52eb43faf..17bcad0dd 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -16,6 +16,7 @@ package org.traccar; import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.socket.DatagramChannel; @@ -23,7 +24,6 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; @@ -41,11 +41,14 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; +@Singleton +@ChannelHandler.Sharable public class MainEventHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(MainEventHandler.class); @@ -57,17 +60,15 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Storage storage; private final ConnectionManager connectionManager; private final StatisticsManager statisticsManager; - private final BroadcastService broadcastService; @Inject public MainEventHandler( Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager, - StatisticsManager statisticsManager, BroadcastService broadcastService) { + StatisticsManager statisticsManager) { this.cacheManager = cacheManager; this.storage = storage; this.connectionManager = connectionManager; this.statisticsManager = statisticsManager; - this.broadcastService = broadcastService; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 94669915b..c4cda578e 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -99,10 +99,11 @@ public class MainModule extends AbstractModule { protected void configure() { bindConstant().annotatedWith(Names.named("configFile")).to(configFile); bind(Config.class).asEagerSingleton(); - bind(Storage.class).to(DatabaseStorage.class); + bind(Storage.class).to(DatabaseStorage.class).in(Scopes.SINGLETON); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } + @Singleton @Provides public static ObjectMapper provideObjectMapper(Config config) { ObjectMapper objectMapper = new ObjectMapper(); @@ -114,6 +115,7 @@ public class MainModule extends AbstractModule { return objectMapper; } + @Singleton @Provides public static Client provideClient(ObjectMapperContextResolver objectMapperContextResolver) { return ClientBuilder.newClient().register(objectMapperContextResolver); @@ -130,6 +132,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static MailManager provideMailManager(Config config, StatisticsManager statisticsManager) { if (config.getBoolean(Keys.MAIL_DEBUG)) { @@ -265,6 +268,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static GeolocationHandler provideGeolocationHandler( Config config, @Nullable GeolocationProvider geolocationProvider, CacheManager cacheManager, @@ -275,6 +279,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static GeocoderHandler provideGeocoderHandler( Config config, @Nullable Geocoder geocoder, CacheManager cacheManager) { @@ -284,6 +289,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static SpeedLimitHandler provideSpeedLimitHandler(@Nullable SpeedLimitProvider speedLimitProvider) { if (speedLimitProvider != null) { @@ -302,6 +308,7 @@ public class MainModule extends AbstractModule { return new NullBroadcastService(); } + @Singleton @Provides public static EventForwarder provideEventForwarder(Config config, Client client, CacheManager cacheManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index d0aa32e53..9b26c8875 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -33,6 +33,7 @@ import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -52,6 +53,7 @@ import java.util.TimeZone; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +@Singleton @ChannelHandler.Sharable public class WebDataHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/api/CorsResponseFilter.java b/src/main/java/org/traccar/api/CorsResponseFilter.java index 5375e207f..67d0341a1 100644 --- a/src/main/java/org/traccar/api/CorsResponseFilter.java +++ b/src/main/java/org/traccar/api/CorsResponseFilter.java @@ -20,11 +20,13 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import java.io.IOException; +@Singleton public class CorsResponseFilter implements ContainerResponseFilter { private final String allowed; diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 1e82a4cf2..32487f06b 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -28,9 +28,11 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.security.GeneralSecurityException; +@Singleton public class LoginService { private final Storage storage; diff --git a/src/main/java/org/traccar/api/signature/CryptoManager.java b/src/main/java/org/traccar/api/signature/CryptoManager.java index 8a3e7704c..249d5bd97 100644 --- a/src/main/java/org/traccar/api/signature/CryptoManager.java +++ b/src/main/java/org/traccar/api/signature/CryptoManager.java @@ -21,6 +21,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.KeyPair; @@ -33,6 +34,7 @@ import java.security.spec.ECGenParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +@Singleton public class CryptoManager { private final Storage storage; diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java index a352ecc10..6a0d90b40 100644 --- a/src/main/java/org/traccar/api/signature/TokenManager.java +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -21,11 +21,13 @@ import org.apache.commons.codec.binary.Base64; import org.traccar.storage.StorageException; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Date; import java.util.concurrent.TimeUnit; +@Singleton public class TokenManager { private static final int DEFAULT_EXPIRATION_DAYS = 7; diff --git a/src/main/java/org/traccar/database/MediaManager.java b/src/main/java/org/traccar/database/MediaManager.java index 2b3e3e1ee..c1ef810ee 100644 --- a/src/main/java/org/traccar/database/MediaManager.java +++ b/src/main/java/org/traccar/database/MediaManager.java @@ -22,6 +22,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -34,6 +35,7 @@ import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; +@Singleton public class MediaManager { private static final Logger LOGGER = LoggerFactory.getLogger(MediaManager.class); diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 5be627f2a..5ea89fcac 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -36,11 +36,13 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; +@Singleton public class NotificationManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 82ac4e804..c9f1f63d7 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -40,7 +40,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class ComputedAttributesHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 1fa47cfaa..e5c9bc29a 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -25,7 +25,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class CopyAttributesHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java index f6a20628b..89255a5fe 100644 --- a/src/main/java/org/traccar/handler/DefaultDataHandler.java +++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java @@ -25,7 +25,9 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class DefaultDataHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index 87c4a81c9..30dc9ff2b 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -25,9 +25,11 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.math.BigDecimal; import java.math.RoundingMode; +@Singleton @ChannelHandler.Sharable public class DistanceHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index 54a1a0c25..c10fe9064 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -22,7 +22,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class EngineHoursHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 37f5cd566..f09cb16a3 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -35,8 +35,10 @@ import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Date; +@Singleton @ChannelHandler.Sharable public class FilterHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java index f760457a3..ccbde9fe5 100644 --- a/src/main/java/org/traccar/handler/HemisphereHandler.java +++ b/src/main/java/org/traccar/handler/HemisphereHandler.java @@ -22,7 +22,9 @@ import org.traccar.config.Keys; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class HemisphereHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 25ee615c5..10312f9b3 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -22,7 +22,9 @@ import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class MotionHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/RemoteAddressHandler.java b/src/main/java/org/traccar/handler/RemoteAddressHandler.java index 809f67ca2..e18d34ef2 100644 --- a/src/main/java/org/traccar/handler/RemoteAddressHandler.java +++ b/src/main/java/org/traccar/handler/RemoteAddressHandler.java @@ -23,8 +23,10 @@ import org.traccar.config.Keys; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; import java.net.InetSocketAddress; +@Singleton @ChannelHandler.Sharable public class RemoteAddressHandler extends ChannelInboundHandlerAdapter { diff --git a/src/main/java/org/traccar/handler/SpeedLimitHandler.java b/src/main/java/org/traccar/handler/SpeedLimitHandler.java index 0469b9f16..0c6025999 100644 --- a/src/main/java/org/traccar/handler/SpeedLimitHandler.java +++ b/src/main/java/org/traccar/handler/SpeedLimitHandler.java @@ -24,7 +24,9 @@ import org.traccar.model.Position; import org.traccar.speedlimit.SpeedLimitProvider; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class SpeedLimitHandler extends ChannelInboundHandlerAdapter { diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java index 439c076c7..c98b0bd4c 100644 --- a/src/main/java/org/traccar/handler/TimeHandler.java +++ b/src/main/java/org/traccar/handler/TimeHandler.java @@ -24,10 +24,12 @@ import org.traccar.config.Keys; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +@Singleton @ChannelHandler.Sharable public class TimeHandler extends ChannelInboundHandlerAdapter { diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java index 75626ca6c..9f77df989 100644 --- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -26,7 +26,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class AlertEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java index 3c2fa6a97..51bbd82d6 100644 --- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java @@ -24,9 +24,11 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class BehaviorEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java index 858f84e09..772176e9c 100644 --- a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java +++ b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java @@ -23,7 +23,9 @@ import org.traccar.model.Event; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class CommandResultEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java index 1ad66ba64..51fdc0307 100644 --- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -23,9 +23,11 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class DriverEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java index d5d4ab9be..462cc4223 100644 --- a/src/main/java/org/traccar/handler/events/FuelEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -25,8 +25,10 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class FuelEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 70bdb84cb..b1be7e8ad 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -33,11 +33,13 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 3c5ac3545..b2e9a3325 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -27,7 +27,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class IgnitionEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index be3e9bf8d..4fcfcd079 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -26,7 +26,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class MaintenanceEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/MediaEventHandler.java b/src/main/java/org/traccar/handler/events/MediaEventHandler.java index 5b9013fad..a49e08e8d 100644 --- a/src/main/java/org/traccar/handler/events/MediaEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MediaEventHandler.java @@ -20,10 +20,12 @@ import org.traccar.model.Event; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; +@Singleton @ChannelHandler.Sharable public class MediaEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 0777f353a..3511cf682 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -34,9 +34,11 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index c03b8eb7b..3928fcc88 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -37,9 +37,11 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class OverspeedEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index fa244d9b4..9ee3b97b6 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -28,7 +28,9 @@ import org.traccar.model.User; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class NotificationFormatter { private final CacheManager cacheManager; diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index be894af96..444f4a7c2 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -30,6 +30,7 @@ import org.traccar.model.User; import org.traccar.storage.StorageException; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -37,6 +38,7 @@ import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.util.Locale; +@Singleton public class TextTemplateFormatter { private static final Logger LOGGER = LoggerFactory.getLogger(TextTemplateFormatter.class); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 75571cfc4..19fde6756 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -24,8 +24,10 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.mail.MessagingException; +@Singleton public class NotificatorMail implements Notificator { private final MailManager mailManager; diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 105cb27f0..e00db0579 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -24,9 +24,11 @@ import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +@Singleton public class NotificatorPushover implements Notificator { private final NotificationFormatter notificationFormatter; diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 544b67a5e..e37d10888 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -25,7 +25,9 @@ import org.traccar.notification.NotificationFormatter; import org.traccar.sms.SmsManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class NotificatorSms implements Notificator { private final SmsManager smsManager; diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index a00cd36f1..38e87c222 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -25,9 +25,11 @@ import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +@Singleton public class NotificatorTelegram implements Notificator { private final NotificationFormatter notificationFormatter; diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 123b16ad8..9ae39f975 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -24,9 +24,11 @@ import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +@Singleton public class NotificatorTraccar implements Notificator { private final NotificationFormatter notificationFormatter; diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index f495042a5..deabeade1 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -16,7 +16,6 @@ */ package org.traccar.notificators; -import org.traccar.broadcast.BroadcastService; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; @@ -24,19 +23,18 @@ import org.traccar.notification.NotificationFormatter; import org.traccar.session.ConnectionManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public final class NotificatorWeb implements Notificator { private final ConnectionManager connectionManager; - private final BroadcastService broadcastService; private final NotificationFormatter notificationFormatter; @Inject public NotificatorWeb( - ConnectionManager connectionManager, BroadcastService broadcastService, - NotificationFormatter notificationFormatter) { + ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { this.connectionManager = connectionManager; - this.broadcastService = broadcastService; this.notificationFormatter = notificationFormatter; } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 57ed4d148..1de774dab 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -52,6 +52,7 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -67,6 +68,7 @@ import java.util.Locale; import java.util.Objects; import java.util.stream.Collectors; +@Singleton public class ReportUtils { private final Config config; diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java index c28cbeed4..52db97b74 100644 --- a/src/main/java/org/traccar/reports/common/TripsConfig.java +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -20,7 +20,9 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class TripsConfig { @Inject diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 62ac338eb..a7ac4d6b2 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -52,7 +52,6 @@ import org.traccar.api.security.SecurityRequestFilter; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; @@ -76,7 +75,6 @@ public class WebServer implements LifecycleObject { private final Config config; private final Server server; - @Inject public WebServer(Injector injector, Config config) { this.injector = injector; this.config = config; -- cgit v1.2.3 From 79b3c9dd2a5ad82010ebabcd9a15bd52a1a2b765 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 08:46:10 -0700 Subject: Remove duplicate class --- .../java/org/traccar/api/ObjectMapperProvider.java | 37 ---------------------- src/main/java/org/traccar/web/WebServer.java | 4 +-- 2 files changed, 2 insertions(+), 39 deletions(-) delete mode 100644 src/main/java/org/traccar/api/ObjectMapperProvider.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java deleted file mode 100644 index d63a4b9b0..000000000 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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.api; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import javax.inject.Inject; -import javax.ws.rs.ext.ContextResolver; - -public class ObjectMapperProvider implements ContextResolver { - - private final ObjectMapper objectMapper; - - @Inject - public ObjectMapperProvider(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - @Override - public ObjectMapper getContext(Class type) { - return objectMapper; - } - -} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index a7ac4d6b2..79d19cc9b 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -45,12 +45,12 @@ import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; import org.traccar.api.CorsResponseFilter; import org.traccar.api.DateParameterConverterProvider; -import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; import org.traccar.api.resource.ServerResource; import org.traccar.api.security.SecurityRequestFilter; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.ObjectMapperContextResolver; import javax.servlet.DispatcherType; import javax.servlet.ServletException; @@ -178,7 +178,7 @@ public class WebServer implements LifecycleObject { ResourceConfig resourceConfig = new ResourceConfig(); resourceConfig.registerClasses( JacksonFeature.class, - ObjectMapperProvider.class, + ObjectMapperContextResolver.class, DateParameterConverterProvider.class, SecurityRequestFilter.class, CorsResponseFilter.class, -- cgit v1.2.3 From b06dd882bf7b8e2067240d5957315499836138c8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 11:15:46 -0700 Subject: Update Java dependencies --- build.gradle | 40 ++++++++++++------------ src/main/java/org/traccar/helper/BufferUtil.java | 18 +++++------ 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index a9d97a825..6dcf6871a 100644 --- a/build.gradle +++ b/build.gradle @@ -10,10 +10,10 @@ repositories { } ext { - guiceVersion = "5.0.1" - jettyVersion = "10.0.7" // jetty 11 javax to jakarta - jerseyVersion = "2.36" // jersey 3 javax to jakarta - jacksonVersion = "2.13.3" // same version as jersey-media-json-jackson dependency + guiceVersion = "5.1.0" + jettyVersion = "10.0.12" // jetty 11 javax to jakarta + jerseyVersion = "2.37" // jersey 3 javax to jakarta + jacksonVersion = "2.13.4" // same version as jersey-media-json-jackson dependency protobufVersion = "3.21.7" } @@ -41,13 +41,13 @@ enforce { dependencies { implementation "commons-codec:commons-codec:1.15" - implementation "com.h2database:h2:2.0.206" - implementation "mysql:mysql-connector-java:8.0.27" - implementation "org.postgresql:postgresql:42.3.1" - implementation "com.microsoft.sqlserver:mssql-jdbc:9.4.1.jre11" + implementation "com.h2database:h2:2.1.214" + implementation "mysql:mysql-connector-java:8.0.30" + implementation "org.postgresql:postgresql:42.5.0" + implementation "com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre11" implementation "com.zaxxer:HikariCP:5.0.1" - implementation "io.netty:netty-all:4.1.66.Final" - implementation "org.slf4j:slf4j-jdk14:2.0.0-alpha6" + implementation "io.netty:netty-all:4.1.82.Final" + implementation "org.slf4j:slf4j-jdk14:2.0.3" implementation "com.google.inject:guice:$guiceVersion" implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" @@ -65,29 +65,29 @@ dependencies { implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" - implementation "org.liquibase:liquibase-core:4.7.0" + implementation "org.liquibase:liquibase-core:4.16.1" implementation "com.sun.mail:javax.mail:1.6.2" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) implementation "org.jxls:jxls-poi:1.0.16" // needs upgrade (wait for jexl 4) - implementation "org.apache.velocity:velocity:1.7" - implementation "org.apache.velocity:velocity-tools:2.0" + implementation "org.apache.velocity:velocity:1.7" // needs upgrade + implementation "org.apache.velocity:velocity-tools:2.0" // needs upgrade implementation "org.apache.commons:commons-collections4:4.4" - implementation "org.mnode.ical4j:ical4j:3.1.2" + implementation "org.mnode.ical4j:ical4j:3.2.5" implementation "org.locationtech.spatial4j:spatial4j:0.8" - implementation "org.locationtech.jts:jts-core:1.18.2" - implementation "net.java.dev.jna:jna-platform:5.10.0" + implementation "org.locationtech.jts:jts-core:1.19.0" + implementation "net.java.dev.jna:jna-platform:5.12.1" implementation "com.github.jnr:jnr-posix:3.1.15" implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "javax.xml.bind:jaxb-api:2.3.1" - implementation "com.sun.xml.bind:jaxb-core:3.0.2" - implementation "com.sun.xml.bind:jaxb-impl:3.0.2" + implementation "com.sun.xml.bind:jaxb-core:3.0.2" // needs upgrade + implementation "com.sun.xml.bind:jaxb-impl:3.0.2" // needs upgrade implementation "javax.activation:activation:1.1.1" - implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" + implementation "com.amazonaws:aws-java-sdk-sns:1.12.314" implementation ("com.google.firebase:firebase-admin:9.0.0") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' } testImplementation "junit:junit:4.13.2" - testImplementation "org.mockito:mockito-core:3.+" + testImplementation "org.mockito:mockito-core:4.+" } task copyDependencies(type: Copy) { diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index 0dbe0a4ad..d1025f548 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -59,16 +59,16 @@ public final class BufferUtil { } public static int indexOf(ByteBuf needle, ByteBuf haystack, int startIndex, int endIndex) { - ByteBuf wrappedHaystack; - if (startIndex == haystack.readerIndex() && endIndex == haystack.writerIndex()) { - wrappedHaystack = haystack; - } else { - wrappedHaystack = Unpooled.wrappedBuffer(haystack); - wrappedHaystack.readerIndex(startIndex - haystack.readerIndex()); - wrappedHaystack.writerIndex(endIndex - haystack.readerIndex()); + int originalReaderIndex = haystack.readerIndex(); + int originalWriterIndex = haystack.writerIndex(); + try { + haystack.readerIndex(startIndex); + haystack.writerIndex(endIndex); + return ByteBufUtil.indexOf(needle, haystack); + } finally { + haystack.readerIndex(originalReaderIndex); + haystack.writerIndex(originalWriterIndex); } - int result = ByteBufUtil.indexOf(needle, wrappedHaystack); - return result < 0 ? result : startIndex + result; } } -- cgit v1.2.3 From 1a8766d8d7a6635d90d11a80935cde256d8a6dbb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 19:14:54 -0700 Subject: Use IP as id for NMEA --- src/main/java/org/traccar/protocol/T55ProtocolDecoder.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 1529aae29..90382439e 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -28,6 +28,7 @@ import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.DatagramChannel; import java.util.Date; @@ -378,6 +379,9 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } deviceSession = getDeviceSession(channel, remoteAddress, id); sentence = sentence.substring(index); + } else if (remoteAddress instanceof InetSocketAddress) { + String host = ((InetSocketAddress) remoteAddress).getHostString(); + deviceSession = getDeviceSession(channel, remoteAddress, host); } else { deviceSession = getDeviceSession(channel, remoteAddress); } -- cgit v1.2.3 From 471de2a758b063cc8d6dd5321cbc459c70b88fd8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Oct 2022 17:32:10 -0700 Subject: Safer cache request --- src/main/java/org/traccar/session/cache/CacheManager.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 64397b368..ed67ed70e 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -48,6 +48,7 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -102,7 +103,11 @@ public class CacheManager implements BroadcastInterface { try { lock.readLock().lock(); return deviceLinks.get(deviceId).get(clazz).stream() - .map(id -> deviceCache.get(new CacheKey(clazz, id)).getValue()) + .map(id -> { + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + return cacheValue != null ? cacheValue.getValue() : null; + }) + .filter(Objects::nonNull) .collect(Collectors.toList()); } finally { lock.readLock().unlock(); -- cgit v1.2.3 From bcd0d17008c2c3e3ccede34a618feac53b199d02 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Oct 2022 18:53:33 -0700 Subject: Concox Vl502 IMEI device id --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 15 +++++++++++++-- .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 0639b9dcf..0eded4b42 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -160,6 +160,17 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return dateBuilder.getDate(); } + private String decodeId(ByteBuf id) { + String serial = ByteBufUtil.hexDump(id); + if (serial.matches("[0-9]+")) { + return serial; + } else { + long imei = id.readUnsignedShort(); + imei = (imei << 32) + id.readUnsignedInt(); + return String.valueOf(imei); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -193,7 +204,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { index = buf.readUnsignedShort(); } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(id)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, decodeId(id)); if (deviceSession == null) { return null; } @@ -208,7 +219,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { ByteBuf response = Unpooled.buffer(); response.writeShort(index); response.writeByte(RESULT_SUCCESS); - response.writeBytes(ByteBufUtil.hexDump(id).getBytes(StandardCharsets.US_ASCII)); + response.writeBytes(decodeId(id).getBytes(StandardCharsets.US_ASCII)); channel.writeAndFlush(new NetworkMessage( formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 3661a0202..f7873ef08 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyNull(decoder, binary( + "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( "7e0200005e01229130231209e300000000000c002300d264a305ff322300160000000022091514493503020000a70400000000ac0400000000e5020003e62c01bc5729009ca319bbff0002dd34020754fe1a83393c03bc572900ce371a6133d704dd34020751551d00fefb9a7e"), Position.PREFIX_TEMP + 4, 29.0); -- cgit v1.2.3 From 205ed7965ae97ee6cf14deb8ec4dc94cdae75dfe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 07:11:19 -0700 Subject: Support RFTRACK commands --- src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java index 540c3ce0b..b3ebbbf9a 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.Protocol; import org.traccar.model.CellTower; +import org.traccar.model.Command; import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.session.DeviceSession; @@ -108,7 +109,11 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { position.setNetwork(network); } - sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer("{}", StandardCharsets.UTF_8)); + String response = "{}"; + for (Command command : getCommandsManager().readQueuedCommands(position.getDeviceId(), 1)) { + response = command.getString(Command.KEY_DATA); + } + sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(response, StandardCharsets.UTF_8)); return position; } -- cgit v1.2.3 From 525fb440430343a73a8ed402677fa24c01262372 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 07:25:59 -0700 Subject: Additional RFTRACK data --- .../traccar/protocol/RfTrackProtocolDecoder.java | 36 +++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java index b3ebbbf9a..be9b23e37 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -73,7 +73,29 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { position.setDeviceTime(new Date(Long.parseLong(value))); break; case "bat": - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value) & 0xff); + int battery = Integer.parseInt(value); + position.set(Position.KEY_BATTERY_LEVEL, battery & 0xff); + position.set("plugStatus", (battery >> 8) & 0x0f); + position.set(Position.KEY_CHARGE, ((battery >> 12) & 0x0f) == 1); + break; + case "id": + position.set("braceletId", value); + break; + case "rc": + int braceletCode = Integer.parseInt(value); + position.set("braceletCode", braceletCode & 0xffff); + position.set("braceletStatus", braceletCode >> 16); + break; + case "idt": + long braceletTime = Long.parseLong(value); + position.set("lastHeartbeat", (braceletTime >> 45) * 10); + position.set("lastPaired", ((braceletTime >> 30) & 0xffff) * 10); + position.set("lastUnpaired", ((braceletTime >> 15) & 0xffff) * 10); + break; + case "mt": + int vibrationTime = Integer.parseInt(value); + position.set("vibrationDevice", (vibrationTime & 0x7fff) * 10); + position.set("vibrationBracelet", (vibrationTime >> 15) * 10); break; case "gps": JsonObject location = Json.createReader(new StringReader(value)).readObject(); @@ -95,6 +117,18 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { mcc, mnc, cell.getInt("l"), cell.getInt("c"), cell.getInt("b"))); } break; + case "dbm": + position.set(Position.KEY_RSSI, Integer.parseInt(value)); + break; + case "bar": + position.set("pressure", Double.parseDouble(value)); + break; + case "cob": + position.set("pressureChanges", value); + break; + case "u_ids": + position.set("unpairedIds", value); + break; default: break; } -- cgit v1.2.3 From 2e0cdf2cec9be08392be2ae8826e14bc757db186 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 08:45:12 -0700 Subject: Fix commands linked to group --- src/main/java/org/traccar/api/resource/CommandResource.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 636b45023..92804e725 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -27,6 +27,7 @@ import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.Typed; +import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -82,7 +83,15 @@ public class CommandResource extends ExtendedObjectResource { public Collection get(@QueryParam("deviceId") long deviceId) throws StorageException { permissionsService.checkPermission(Device.class, getUserId(), deviceId); BaseProtocol protocol = getDeviceProtocol(deviceId); - return get(false, 0, 0, deviceId).stream().filter(command -> { + + var commands = storage.getObjects(Command.class, new Request( + new Columns.All(), + Condition.merge(List.of( + new Condition.Permission(User.class, getUserId(), Command.class), + new Condition.Permission(Device.class, deviceId, baseClass) + )))); + + return commands.stream().filter(command -> { String type = command.getType(); if (protocol != null) { return command.getTextChannel() && protocol.getSupportedTextCommands().contains(type) -- cgit v1.2.3 From bb78e15201e88fba4c71bb08d98d0f0bc5acecbf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 08:52:25 -0700 Subject: Decode RFTRACK WiFi info --- src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java | 9 +++++++++ .../java/org/traccar/protocol/RfTrackProtocolDecoderTest.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java index be9b23e37..28a3ac29c 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -26,6 +26,7 @@ import org.traccar.model.CellTower; import org.traccar.model.Command; import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import org.traccar.session.DeviceSession; import javax.json.Json; @@ -126,6 +127,14 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { case "cob": position.set("pressureChanges", value); break; + case "wifi": + JsonArray wifiInfo = Json.createReader(new StringReader(value)).readArray(); + for (int i = 0; i < wifiInfo.size(); i++) { + JsonObject wifi = wifiInfo.getJsonObject(i); + network.addWifiAccessPoint(WifiAccessPoint.from( + wifi.getString("m").replace('-', ':'), wifi.getInt("l"))); + } + break; case "u_ids": position.set("unpairedIds", value); break; diff --git a/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java index 19a654fa6..df19f01c6 100644 --- a/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java @@ -12,7 +12,7 @@ public class RfTrackProtocolDecoderTest extends ProtocolTest { 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"))); + 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\",\"m\":\"30-B4-9E-DD-F8-2D\"}]&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 75f1bed91c1669e1442c2ab9ea9af0b5754db4db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 6 Oct 2022 06:42:12 -0700 Subject: Fix TAT100 cell decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 8 ++++---- .../java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 4671a1088..89af20b22 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -347,10 +347,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (position.hasAttribute(mncKey) && position.hasAttribute(lacKey) && position.hasAttribute(cidKey)) { CellTower cellTower = CellTower.from( getConfig().getInteger(Keys.GEOLOCATION_MCC), - (Integer) position.getAttributes().remove(mncKey), - (Integer) position.getAttributes().remove(lacKey), - (Integer) position.getAttributes().remove(cidKey)); - cellTower.setSignalStrength((Integer) position.getAttributes().remove(rssiKey)); + ((Number) position.getAttributes().remove(mncKey)).intValue(), + ((Number) position.getAttributes().remove(lacKey)).intValue(), + ((Number) position.getAttributes().remove(cidKey)).longValue()); + cellTower.setSignalStrength(((Number) position.getAttributes().remove(rssiKey)).intValue()); network.addCellTower(cellTower); } } diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 197391d7f..188c4b6eb 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000000a28e0100000183ac617e3001123eb99b1e142db4000000000000000000001d000900f000005000001503004500011e1801212d01242a012722012a18001100b5000000b600000018000000cd151000431c2d011f6981012047d701226981012347d901256981012647d8012869810129e6f304b0000304b1000304b2000304b30003000100f10000639d0002000b0000000214bf12fe000e0000000029d18c95000001000051b6")); + verifyPositions(decoder, binary( "00000000000004258e0400000182a701b49301d5d90ab7ebe4aae101be003d12000000f7003d000e00f70100ef0000f00000500500150200c800004501000100001d00001400001600001700007157010701001d00b5000b00b60006004230400018000000cd223f00ce741700430f8900440000000d00010011ffe50012001f0013ffce000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333382e0100000053a6fb624588040001ba86064f0eae51c0fdaf4d3de500000182a701b82001d5d90ab7ebe4aae101be003d12000000f0003c000d00ef0000f00100500500150200c800004501000100001d00001400001600001700007152010701001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a701bc0801d5d90ab7ebe4aae101be003d12000000fc003d000e00ef0000f00100500500150200c800004501000100001d0000140000160000170000714d01070100fc01001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a7018d8d01d5d8ffa6ebe4a0ca01be006111000000f70001000100f70500000000000000000400003a10")); -- cgit v1.2.3 From ab9ff21bec23723132ed8183979be22b67c1cb3c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 6 Oct 2022 07:04:31 -0700 Subject: Fix Huabao responses --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 0eded4b42..27555d46d 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -165,8 +165,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { if (serial.matches("[0-9]+")) { return serial; } else { - long imei = id.readUnsignedShort(); - imei = (imei << 32) + id.readUnsignedInt(); + long imei = id.getUnsignedShort(0); + imei = (imei << 32) + id.getUnsignedInt(2); return String.valueOf(imei); } } -- cgit v1.2.3 From dfaef4eca85a065e35c360fd6f712b2ad62f2e7a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 7 Oct 2022 06:30:03 -0700 Subject: Fix attributes test (fix #4956) --- src/main/java/org/traccar/api/resource/AttributeResource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index fb74b9bbe..f85e90133 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -29,7 +29,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.traccar.api.ExtendedObjectResource; -import org.traccar.config.Config; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; @@ -45,7 +44,7 @@ import org.traccar.storage.query.Request; public class AttributeResource extends ExtendedObjectResource { @Inject - private Config config; + private ComputedAttributesHandler computedAttributesHandler; public AttributeResource() { super(Attribute.class); @@ -61,7 +60,7 @@ public class AttributeResource extends ExtendedObjectResource { new Columns.All(), new Condition.LatestPositions(deviceId))); - Object result = new ComputedAttributesHandler(config, null).computeAttribute(entity, position); + Object result = computedAttributesHandler.computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { case "number": -- cgit v1.2.3 From c801d33f44ae346d01e19e47a3b97c8405f4d5b4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 12 Oct 2022 17:47:35 -0700 Subject: Fix G1RUS decoding --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 8 ++++++-- .../org/traccar/protocol/G1rusProtocolDecoderTest.java | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index e974e446d..17cfbc1eb 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -124,8 +124,12 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; + buf.readUnsignedByte(); // header + buf.readUnsignedByte(); // version + int type = buf.readUnsignedByte(); String imei = String.valueOf(buf.readLong()); + buf.readerIndex(buf.readerIndex() - 1); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; @@ -144,14 +148,14 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.to(subtype, 6) == MSG_REGULAR) { positions.add(decodeRegular(deviceSession, buf, subtype)); } else { - buf.skipBytes(length); + buf.skipBytes(length - 1); } } return positions.isEmpty() ? null : positions; } - buf.skipBytes(2); + buf.readUnsignedShort(); // checksum buf.readUnsignedByte(); // tail return null; diff --git a/src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java new file mode 100644 index 000000000..c8b4e35fe --- /dev/null +++ b/src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class G1rusProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new G1rusProtocolDecoder(null)); + + verifyPositions(decoder, binary( + "f84604000d85f5e55298004b012ad7d524003d1d0f50726f6d61205361742031303030201556312e31302656312e312e340a03120fa0142b8475a157050401846dfc060175120a29a10d02440111002100310041005107d10ef8")); + + } + +} -- cgit v1.2.3 From acedd28b8584a18022d9e2343558f9acbad1666f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Oct 2022 07:22:20 -0700 Subject: Support OBD6 status message --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 38 +++++++++++++++------- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 4 +++ 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index a93c11cbc..212b4245f 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -118,6 +118,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { S5, SPACE10X, STANDARD, + OBD6, } private Variant variant; @@ -346,7 +347,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private void decodeStatus(Position position, ByteBuf buf, boolean batteryLevel) { + private void decodeStatus(Position position, ByteBuf buf) { int status = buf.readUnsignedByte(); @@ -381,13 +382,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { default: break; } - - if (batteryLevel) { - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); - } else { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - } - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } private String decodeAlarm(short value) { @@ -793,8 +787,22 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasStatus(type)) { - decodeStatus(position, buf, true); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + decodeStatus(position, buf); + if (variant == Variant.OBD6) { + int signal = buf.readUnsignedShort(); + int satellites = BitUtil.between(signal, 10, 15) + BitUtil.between(signal, 5, 10); + position.set(Position.KEY_SATELLITES, satellites); + position.set(Position.KEY_RSSI, BitUtil.to(signal, 5)); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + buf.readUnsignedByte(); // language + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + buf.readUnsignedByte(); // working mode + position.set(Position.KEY_POWER, buf.readUnsignedShort() / 100.0); + } else { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + } } if (type == MSG_GPS_LBS_1) { @@ -823,10 +831,14 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } } else if (variant == Variant.VXT01) { - decodeStatus(position, buf, false); + decodeStatus(position, buf); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); buf.readUnsignedByte(); // alarm extension } else if (variant == Variant.S5) { - decodeStatus(position, buf, false); + decodeStatus(position, buf); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("oil", buf.readUnsignedShort()); int temperature = buf.readUnsignedByte(); @@ -1355,6 +1367,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.S5; } else if (header == 0x7878 && type == MSG_LBS_STATUS && length >= 0x17) { variant = Variant.SPACE10X; + } else if (header == 0x7878 && type == MSG_STATUS && length == 0x13) { + variant = Variant.OBD6; } else { variant = Variant.STANDARD; } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index ebda38823..d1789bb16 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "7878131302801900002e42016f000000003a0177ef180d0a"), + Position.KEY_POWER, 3.67); + verifyAttribute(decoder, binary( "78782526160913063918c002780fab0c44750f00040008027f14084c0038420600030c020007398e0d0a"), Position.KEY_ALARM, Position.ALARM_TAMPERING); -- cgit v1.2.3 From 4c8e98ed409df6e12128591eb1d8d0cf0856deb7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Oct 2022 10:31:54 -0700 Subject: Refactor database code (fix #4961) --- src/main/java/org/traccar/MainEventHandler.java | 2 +- .../java/org/traccar/api/BaseObjectResource.java | 11 +++-- src/main/java/org/traccar/api/MediaFilter.java | 2 +- .../org/traccar/api/resource/CommandResource.java | 2 +- .../org/traccar/api/resource/DeviceResource.java | 8 ++-- .../org/traccar/api/resource/EventResource.java | 2 +- .../org/traccar/api/resource/PasswordResource.java | 7 +-- .../org/traccar/api/resource/PositionResource.java | 2 +- .../org/traccar/api/resource/ServerResource.java | 2 +- .../org/traccar/api/resource/SessionResource.java | 2 +- .../org/traccar/api/resource/UserResource.java | 3 +- .../org/traccar/api/security/LoginService.java | 7 +-- .../traccar/api/security/PermissionsService.java | 4 +- .../java/org/traccar/database/CommandsManager.java | 8 ++-- .../org/traccar/database/DeviceLookupService.java | 2 +- .../java/org/traccar/handler/FilterHandler.java | 2 +- .../handler/events/GeofenceEventHandler.java | 3 +- .../traccar/handler/events/MotionEventHandler.java | 2 +- .../handler/events/OverspeedEventHandler.java | 2 +- .../org/traccar/helper/model/PositionUtil.java | 2 +- src/main/java/org/traccar/model/Device.java | 7 ++- .../org/traccar/reports/EventsReportProvider.java | 4 +- .../org/traccar/reports/GpxExportProvider.java | 2 +- .../org/traccar/reports/KmlExportProvider.java | 2 +- .../org/traccar/reports/RouteReportProvider.java | 2 +- .../org/traccar/reports/StopsReportProvider.java | 2 +- .../org/traccar/reports/TripsReportProvider.java | 2 +- .../org/traccar/reports/common/ReportUtils.java | 4 +- .../org/traccar/session/ConnectionManager.java | 4 +- .../org/traccar/session/cache/CacheManager.java | 12 ++--- .../java/org/traccar/storage/DatabaseStorage.java | 25 +++++----- .../java/org/traccar/storage/QueryBuilder.java | 54 +++++++++++----------- .../java/org/traccar/storage/query/Columns.java | 3 +- .../java/org/traccar/storage/query/Condition.java | 8 +--- 34 files changed, 102 insertions(+), 104 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 17bcad0dd..877f03ae7 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -90,7 +90,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { updatedDevice.setPositionId(position.getId()); storage.updateObject(updatedDevice, new Request( new Columns.Include("positionId"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", updatedDevice.getId()))); cacheManager.updatePosition(position); connectionManager.updatePosition(true, position); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 0ec2bfeaa..904781e54 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -56,7 +56,7 @@ public abstract class BaseObjectResource extends BaseResour public Response getSingle(@PathParam("id") long id) throws StorageException { permissionsService.checkPermission(baseClass, getUserId(), id); T entity = storage.getObject(baseClass, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); + new Columns.All(), new Condition.Equals("id", id))); if (entity != null) { return Response.ok(entity).build(); } else { @@ -86,7 +86,7 @@ public abstract class BaseObjectResource extends BaseResour if (entity instanceof User) { User before = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + new Columns.All(), new Condition.Equals("id", entity.getId()))); permissionsService.checkUserUpdate(getUserId(), before, (User) entity); } else if (entity instanceof Group) { Group group = (Group) entity; @@ -97,12 +97,13 @@ public abstract class BaseObjectResource extends BaseResour storage.updateObject(entity, new Request( new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", entity.getId()))); if (entity instanceof User) { User user = (User) entity; if (user.getHashedPassword() != null) { storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", entity.getId()))); } } cacheManager.updateOrInvalidate(true, entity); @@ -117,7 +118,7 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), baseClass, false); permissionsService.checkPermission(baseClass, getUserId(), id); - storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); + storage.removeObject(baseClass, new Request(new Condition.Equals("id", id))); cacheManager.invalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index 6d95c66a8..ab75bdc5d 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -84,7 +84,7 @@ public class MediaFilter implements Filter { String[] parts = path != null ? path.split("/") : null; if (parts != null && parts.length >= 2) { Device device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", parts[1]))); + new Columns.All(), new Condition.Equals("uniqueId", parts[1]))); if (device != null) { permissionsServiceProvider.get().checkPermission(Device.class, userId, device.getId()); chain.doFilter(request, response); diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 92804e725..80b9fd18f 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -110,7 +110,7 @@ public class CommandResource extends ExtendedObjectResource { permissionsService.checkPermission(Command.class, getUserId(), entity.getId()); long deviceId = entity.getDeviceId(); entity = storage.getObject(baseClass, new Request( - new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + new Columns.All(), new Condition.Equals("id", entity.getId()))); entity.setDeviceId(deviceId); } else { permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 1d9bc20ec..c0b0cea0d 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -84,14 +84,14 @@ public class DeviceResource extends BaseObjectResource { result.addAll(storage.getObjects(Device.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("uniqueId", "uniqueId", uniqueId), + new Condition.Equals("uniqueId", uniqueId), new Condition.Permission(User.class, getUserId(), Device.class))))); } for (Long deviceId : deviceIds) { result.addAll(storage.getObjects(Device.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("id", "id", deviceId), + new Condition.Equals("id", deviceId), new Condition.Permission(User.class, getUserId(), Device.class))))); } return result; @@ -142,7 +142,7 @@ public class DeviceResource extends BaseObjectResource { device.setPositionId(position.getId()); storage.updateObject(device, new Request( new Columns.Include("positionId"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", device.getId()))); try { cacheManager.addDevice(position.getDeviceId()); @@ -169,7 +169,7 @@ public class DeviceResource extends BaseObjectResource { Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("id", "id", deviceId), + new Condition.Equals("id", deviceId), new Condition.Permission(User.class, getUserId(), Device.class)))); if (device != null) { String name = "device"; diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 3870e9af9..afdaf52b5 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -41,7 +41,7 @@ public class EventResource extends BaseResource { @GET public Event get(@PathParam("id") long id) throws StorageException { Event event = storage.getObject(Event.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); + new Columns.All(), new Condition.Equals("id", id))); if (event == null) { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 625ff4cb1..ebf4e3b91 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -59,7 +59,7 @@ public class PasswordResource extends BaseResource { throws StorageException, MessagingException, GeneralSecurityException, IOException { User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("email", "email", email))); + new Columns.All(), new Condition.Equals("email", email))); if (user != null) { var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); velocityContext.put("token", tokenManager.generateToken(user.getId())); @@ -78,11 +78,12 @@ public class PasswordResource extends BaseResource { long userId = tokenManager.verifyToken(token); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); + new Columns.All(), new Condition.Equals("id", userId))); if (user != null) { user.setPassword(password); storage.updateObject(user, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", userId))); return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 7d7921085..042dd1e23 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -67,7 +67,7 @@ public class PositionResource extends BaseResource { var positions = new ArrayList(); for (long positionId : positionIds) { Position position = storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", positionId))); + new Columns.All(), new Condition.Equals("id", positionId))); permissionsService.checkPermission(Device.class, getUserId(), position.getDeviceId()); positions.add(position); } diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index e35cd7d95..e7f0b93ca 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -76,7 +76,7 @@ public class ServerResource extends BaseResource { permissionsService.checkAdmin(getUserId()); storage.updateObject(entity, new Request( new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", entity.getId()))); cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 05f492d73..1e984fbd0 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -122,7 +122,7 @@ public class SessionResource extends BaseResource { public User get(@PathParam("id") long userId) throws StorageException { permissionsService.checkAdmin(getUserId()); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); + new Columns.All(), new Condition.Equals("id", userId))); request.getSession().setAttribute(USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index dd71de4c6..91875ef51 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -100,7 +100,8 @@ public class UserResource extends BaseObjectResource { entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", entity.getId()))); LogAction.create(getUserId(), entity); diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 32487f06b..88bafcfb5 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -58,7 +58,7 @@ public class LoginService { } long userId = tokenManager.verifyToken(token); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); + new Columns.All(), new Condition.Equals("id", userId))); if (user != null) { checkUserEnabled(user); } @@ -66,11 +66,12 @@ public class LoginService { } public User login(String email, String password) throws StorageException { + email = email.trim(); User user = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Or( - new Condition.Equals("email", "email", email.trim()), - new Condition.Equals("login", "email")))); + new Condition.Equals("email", email), + new Condition.Equals("login", email)))); if (user != null) { if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) || !forceLdap && user.isPasswordValid(password)) { diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index ddfaaab94..0d4877fdb 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -62,7 +62,7 @@ public class PermissionsService { user = new ServiceAccountUser(); } else { user = storage.getObject( - User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + User.class, new Request(new Columns.All(), new Condition.Equals("id", userId))); } } return user; @@ -187,7 +187,7 @@ public class PermissionsService { var object = storage.getObject(clazz, new Request( new Columns.Include("id"), new Condition.And( - new Condition.Equals("id", "id", objectId), + new Condition.Equals("id", objectId), new Condition.Permission( User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz)))); if (object == null) { diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 53040ad53..764ea637b 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -69,9 +69,9 @@ public class CommandsManager implements BroadcastInterface { throw new RuntimeException("SMS not configured"); } Device device = storage.getObject(Device.class, new Request( - new Columns.Include("positionId", "phone"), new Condition.Equals("id", "id", deviceId))); + new Columns.Include("positionId", "phone"), new Condition.Equals("id", deviceId))); Position position = storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getPositionId()))); + new Columns.All(), new Condition.Equals("id", device.getPositionId()))); if (position != null) { BaseProtocol protocol = serverManager.getProtocol(position.getProtocol()); protocol.sendTextCommand(device.getPhone(), command); @@ -101,12 +101,12 @@ public class CommandsManager implements BroadcastInterface { try { var commands = storage.getObjects(QueuedCommand.class, new Request( new Columns.All(), - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Order(false, "id"), new Limit(count))); for (var command : commands) { storage.removeObject(QueuedCommand.class, new Request( - new Condition.Equals("id", "id", command.getId()))); + new Condition.Equals("id", command.getId()))); } return commands.stream().map(QueuedCommand::toCommand).collect(Collectors.toList()); } catch (StorageException e) { diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index 9cf0899ee..28910c24a 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -108,7 +108,7 @@ public class DeviceLookupService { for (String uniqueId : uniqueIds) { if (!isThrottled(uniqueId)) { device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); + new Columns.All(), new Condition.Equals("uniqueId", uniqueId))); if (device != null) { lookupSucceeded(uniqueId); break; diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index f09cb16a3..3722f2a22 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -88,7 +88,7 @@ public class FilterHandler extends BaseDataHandler { return storage.getObject(Position.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Condition.Compare("fixTime", "<=", "time", date)), new Order(true, "fixTime"), new Limit(1))); diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index b1be7e8ad..9414f4b31 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -82,7 +82,8 @@ public class GeofenceEventHandler extends BaseEventHandler { try { storage.updateObject(device, new Request( - new Columns.Include("geofenceIds"), new Condition.Equals("id", "id"))); + new Columns.Include("geofenceIds"), + new Condition.Equals("id", device.getId()))); } catch (StorageException e) { throw new RuntimeException("Update device geofences error", e); } diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 3511cf682..1b9763c41 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -76,7 +76,7 @@ public class MotionEventHandler extends BaseEventHandler { try { storage.updateObject(device, new Request( new Columns.Include("motionState", "motionTime", "motionDistance"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", device.getId()))); } catch (StorageException e) { LOGGER.warn("Update device motion error", e); } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 3928fcc88..4d6aa8857 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -113,7 +113,7 @@ public class OverspeedEventHandler extends BaseEventHandler { try { storage.updateObject(device, new Request( new Columns.Include("overspeedState", "overspeedTime", "overspeedGeofenceId"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", device.getId()))); } catch (StorageException e) { LOGGER.warn("Update device overspeed error", e); } diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 31f828947..6c380b81a 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -59,7 +59,7 @@ public final class PositionUtil { return storage.getObjects(Position.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Condition.Between("fixTime", "from", from, "to", to)), new Order("fixTime"))); } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 147b0fd20..7728172cb 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -52,22 +52,22 @@ public class Device extends GroupedModel implements Disableable { private String status; + @QueryIgnore public String getStatus() { return status != null ? status : STATUS_OFFLINE; } - @QueryIgnore public void setStatus(String status) { this.status = status != null ? status.trim() : null; } private Date lastUpdate; + @QueryIgnore public Date getLastUpdate() { return this.lastUpdate; } - @QueryIgnore public void setLastUpdate(Date lastUpdate) { this.lastUpdate = lastUpdate; } @@ -79,18 +79,17 @@ public class Device extends GroupedModel implements Disableable { return positionId; } - @QueryIgnore public void setPositionId(long positionId) { this.positionId = positionId; } private List geofenceIds; + @QueryIgnore public List getGeofenceIds() { return geofenceIds; } - @QueryIgnore public void setGeofenceIds(List geofenceIds) { if (geofenceIds != null) { this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 878c0265d..d0d4fe8bf 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -64,7 +64,7 @@ public class EventsReportProvider { return storage.getObjects(Event.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Condition.Between("eventTime", "from", from, "to", to)), new Order("eventTime"))); } @@ -134,7 +134,7 @@ public class EventsReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceEvents.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/GpxExportProvider.java b/src/main/java/org/traccar/reports/GpxExportProvider.java index f1a0f292d..ccbd97fc3 100644 --- a/src/main/java/org/traccar/reports/GpxExportProvider.java +++ b/src/main/java/org/traccar/reports/GpxExportProvider.java @@ -42,7 +42,7 @@ public class GpxExportProvider { OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { var device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); var positions = PositionUtil.getPositions(storage, deviceId, from, to); try (PrintWriter writer = new PrintWriter(outputStream)) { diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java index e8b5c4278..24fcfb8ab 100644 --- a/src/main/java/org/traccar/reports/KmlExportProvider.java +++ b/src/main/java/org/traccar/reports/KmlExportProvider.java @@ -43,7 +43,7 @@ public class KmlExportProvider { OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { var device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); var positions = PositionUtil.getPositions(storage, deviceId, from, to); var dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 0f618822e..3ee651619 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -80,7 +80,7 @@ public class RouteReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceRoutes.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index ba61ef6a1..ec3fd2215 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -87,7 +87,7 @@ public class StopsReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceStops.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 2d9bcdfbf..265811354 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -87,7 +87,7 @@ public class TripsReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceTrips.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 1de774dab..120dadcf5 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -95,7 +95,7 @@ public class ReportUtils { return storage.getObject(clazz, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("id", "id", objectId), + new Condition.Equals("id", objectId), new Condition.Permission(User.class, userId, clazz)))); } @@ -166,7 +166,7 @@ public class ReportUtils { if (driverUniqueId != null) { Driver driver = storage.getObject(Driver.class, new Request( new Columns.All(), - new Condition.Equals("uniqueId", "uniqueId", driverUniqueId))); + new Condition.Equals("uniqueId", driverUniqueId))); if (driver != null) { return driver.getName(); } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 9e50c9ead..37a42d827 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -215,7 +215,7 @@ public class ConnectionManager implements BroadcastInterface { if (device == null) { try { device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); } catch (StorageException e) { LOGGER.warn("Failed to get device", e); } @@ -265,7 +265,7 @@ public class ConnectionManager implements BroadcastInterface { try { storage.updateObject(device, new Request( new Columns.Include("status", "lastUpdate"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", deviceId))); } catch (StorageException e) { LOGGER.warn("Update device status error", e); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index ed67ed70e..8f2e7ba93 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -201,7 +201,7 @@ public class CacheManager implements BroadcastInterface { public void invalidateObject(boolean local, Class clazz, long id) { try { var object = storage.getObject(clazz, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); + new Columns.All(), new Condition.Equals("id", id))); if (object != null) { updateOrInvalidate(local, object); } else { @@ -286,7 +286,7 @@ public class CacheManager implements BroadcastInterface { Map, Set> links = new HashMap<>(); Device device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); if (device != null) { addObject(deviceId, device); @@ -294,7 +294,7 @@ public class CacheManager implements BroadcastInterface { long groupId = device.getGroupId(); while (groupDepth < GROUP_DEPTH_LIMIT && groupId > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", groupId))); + new Columns.All(), new Condition.Equals("id", groupId))); links.computeIfAbsent(Group.class, k -> new LinkedHashSet<>()).add(group.getId()); addObject(deviceId, group); groupId = group.getGroupId(); @@ -311,7 +311,7 @@ public class CacheManager implements BroadcastInterface { var scheduled = (ScheduledModel) object; if (scheduled.getCalendarId() > 0) { var calendar = storage.getObject(Calendar.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", scheduled.getCalendarId()))); + new Columns.All(), new Condition.Equals("id", scheduled.getCalendarId()))); links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) .add(calendar.getId()); addObject(deviceId, calendar); @@ -336,7 +336,7 @@ public class CacheManager implements BroadcastInterface { addObject(deviceId, notification); if (notification.getCalendarId() > 0) { var calendar = storage.getObject(Calendar.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", notification.getCalendarId()))); + new Columns.All(), new Condition.Equals("id", notification.getCalendarId()))); links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) .add(calendar.getId()); addObject(deviceId, calendar); @@ -348,7 +348,7 @@ public class CacheManager implements BroadcastInterface { if (device.getPositionId() > 0) { devicePositions.put(deviceId, storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + new Columns.All(), new Condition.Equals("id", device.getPositionId())))); } } } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 8ca464147..884c8fca8 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -57,7 +57,7 @@ public class DatabaseStorage extends Storage { if (request.getColumns() instanceof Columns.All) { query.append('*'); } else { - query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); + query.append(formatColumns(request.getColumns().getColumns(clazz, "set"), c -> c)); } query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); @@ -76,16 +76,17 @@ public class DatabaseStorage extends Storage { @Override public long addObject(T entity, Request request) throws StorageException { + List columns = request.getColumns().getColumns(entity.getClass(), "get"); StringBuilder query = new StringBuilder("INSERT INTO "); query.append(getStorageName(entity.getClass())); query.append("("); - query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c)); + query.append(formatColumns(columns, c -> c)); query.append(") VALUES ("); - query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> ':' + c)); + query.append(formatColumns(columns, c -> ':' + c)); query.append(")"); try { QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); - builder.setObject(entity); + builder.setObject(entity, columns); return builder.executeUpdate(); } catch (SQLException e) { throw new StorageException(e); @@ -94,14 +95,15 @@ public class DatabaseStorage extends Storage { @Override public void updateObject(T entity, Request request) throws StorageException { + List columns = request.getColumns().getColumns(entity.getClass(), "get"); StringBuilder query = new StringBuilder("UPDATE "); query.append(getStorageName(entity.getClass())); query.append(" SET "); - query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); + query.append(formatColumns(columns, c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); try { QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); - builder.setObject(entity); + builder.setObject(entity, columns); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -135,12 +137,10 @@ public class DatabaseStorage extends Storage { query.append(Permission.getStorageName(ownerClass, propertyClass)); var conditions = new LinkedList(); if (ownerId > 0) { - conditions.add(new Condition.Equals( - Permission.getKey(ownerClass), Permission.getKey(ownerClass), ownerId)); + conditions.add(new Condition.Equals(Permission.getKey(ownerClass), ownerId)); } if (propertyId > 0) { - conditions.add(new Condition.Equals( - Permission.getKey(propertyClass), Permission.getKey(propertyClass), propertyId)); + conditions.add(new Condition.Equals(Permission.getKey(propertyClass), propertyId)); } Condition combinedCondition = Condition.merge(conditions); query.append(formatCondition(combinedCondition)); @@ -230,9 +230,8 @@ public class DatabaseStorage extends Storage { return results; } - private String formatColumns( - Columns columns, Class clazz, String type, Function mapper) { - return columns.getColumns(clazz, type).stream().map(mapper).collect(Collectors.joining(", ")); + private String formatColumns(List columns, Function mapper) { + return columns.stream().map(mapper).collect(Collectors.joining(", ")); } private String formatCondition(Condition genericCondition) throws StorageException { diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index a58ebe2b4..fa71a8e8f 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -37,10 +37,12 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; @SuppressWarnings("UnusedReturnValue") public final class QueryBuilder { @@ -283,36 +285,32 @@ public final class QueryBuilder { return this; } - public QueryBuilder setObject(Object object) throws SQLException { - - Method[] methods = object.getClass().getMethods(); - - for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 - && !method.getName().equals("getClass")) { - String name = method.getName().substring(3); - try { - if (method.getReturnType().equals(boolean.class)) { - setBoolean(name, (Boolean) method.invoke(object)); - } else if (method.getReturnType().equals(int.class)) { - setInteger(name, (Integer) method.invoke(object)); - } else if (method.getReturnType().equals(long.class)) { - setLong(name, (Long) method.invoke(object), name.endsWith("Id")); - } else if (method.getReturnType().equals(double.class)) { - setDouble(name, (Double) method.invoke(object)); - } else if (method.getReturnType().equals(String.class)) { - setString(name, (String) method.invoke(object)); - } else if (method.getReturnType().equals(Date.class)) { - setDate(name, (Date) method.invoke(object)); - } else if (method.getReturnType().equals(byte[].class)) { - setBlob(name, (byte[]) method.invoke(object)); - } else { - setString(name, objectMapper.writeValueAsString(method.invoke(object))); - } - } catch (IllegalAccessException | InvocationTargetException | JsonProcessingException error) { - LOGGER.warn("Get property error", error); + public QueryBuilder setObject(Object object, List columns) throws SQLException { + + try { + for (String column : columns) { + Method method = object.getClass().getMethod( + "get" + Character.toUpperCase(column.charAt(0)) + column.substring(1)); + if (method.getReturnType().equals(boolean.class)) { + setBoolean(column, (Boolean) method.invoke(object)); + } else if (method.getReturnType().equals(int.class)) { + setInteger(column, (Integer) method.invoke(object)); + } else if (method.getReturnType().equals(long.class)) { + setLong(column, (Long) method.invoke(object), column.endsWith("Id")); + } else if (method.getReturnType().equals(double.class)) { + setDouble(column, (Double) method.invoke(object)); + } else if (method.getReturnType().equals(String.class)) { + setString(column, (String) method.invoke(object)); + } else if (method.getReturnType().equals(Date.class)) { + setDate(column, (Date) method.invoke(object)); + } else if (method.getReturnType().equals(byte[].class)) { + setBlob(column, (byte[]) method.invoke(object)); + } else { + setString(column, objectMapper.writeValueAsString(method.invoke(object))); } } + } catch (ReflectiveOperationException | JsonProcessingException e) { + LOGGER.warn("Set object error", e); } return this; diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 545995b3c..a00400b36 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -17,6 +17,7 @@ package org.traccar.storage.query; import org.traccar.storage.QueryIgnore; +import java.beans.Introspector; import java.lang.reflect.Method; import java.util.Arrays; import java.util.LinkedList; @@ -36,7 +37,7 @@ public abstract class Columns { if (method.getName().startsWith(type) && method.getParameterTypes().length == parameterCount && !method.isAnnotationPresent(QueryIgnore.class) && !method.getName().equals("getClass")) { - columns.add(method.getName().substring(3).toLowerCase()); + columns.add(Introspector.decapitalize(method.getName().substring(3))); } } return columns; diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 136b0402b..08b199052 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -34,12 +34,8 @@ public interface Condition { } class Equals extends Compare { - public Equals(String column, String variable) { - this(column, variable, null); - } - - public Equals(String column, String variable, Object value) { - super(column, "=", variable, value); + public Equals(String column, Object value) { + super(column, "=", column, value); } } -- cgit v1.2.3 From 47579ba635ad87af13f9626923e0168ff53e5178 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Oct 2022 10:35:02 -0700 Subject: Fix lint issues --- src/main/java/org/traccar/storage/QueryBuilder.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index fa71a8e8f..2f4c07406 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -37,12 +37,10 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Set; @SuppressWarnings("UnusedReturnValue") public final class QueryBuilder { -- cgit v1.2.3 From 85cef19d557b3aa0e306c3efe0bdcf8020042775 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 14 Oct 2022 06:29:45 -0700 Subject: MiniFinder Rex bark alarm --- .../java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 8 ++++++-- .../java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 228578571..bec05ffc2 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -50,7 +50,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SERVICES = 0x03; public static final int MSG_RESPONSE = 0x7F; - private String decodeAlarm(int code) { + private String decodeAlarm(long code) { if (BitUtil.check(code, 0)) { return Position.ALARM_LOW_BATTERY; } @@ -181,7 +181,11 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); break; case 0x02: - position.set(Position.KEY_ALARM, decodeAlarm(buf.readIntLE())); + long alarm = buf.readUnsignedIntLE(); + position.set(Position.KEY_ALARM, decodeAlarm(alarm)); + if (BitUtil.check(alarm, 31)) { + position.set("bark", true); + } break; case 0x14: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index a6006d6a7..0809996f6 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -10,6 +10,10 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Minifinder2ProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "ab102600080f1400011001383633393231303339393833343736092429b347633003a96409020000008027b34763"), + "bark", true); + verifyPositions(decoder, binary( "AB103D0035A700000110013836373733303035333430333237390924AC5783620103C250162030CC5F0D5002FB432D00AF005A3158006D0A00000B0931EC5783620A000000")); -- cgit v1.2.3 From 3f01f92125851e325b8e3e4ef679d832fe3dee21 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Oct 2022 06:47:59 -0700 Subject: Fix MS SQL limit (fix #4958) --- .../java/org/traccar/database/CommandsManager.java | 4 +--- .../java/org/traccar/handler/FilterHandler.java | 4 +--- .../java/org/traccar/storage/DatabaseStorage.java | 28 +++++++++++++--------- src/main/java/org/traccar/storage/query/Order.java | 12 +++++++--- .../java/org/traccar/storage/query/Request.java | 6 ----- 5 files changed, 28 insertions(+), 26 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 764ea637b..df399cd7a 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -31,7 +31,6 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; @@ -102,8 +101,7 @@ public class CommandsManager implements BroadcastInterface { var commands = storage.getObjects(QueuedCommand.class, new Request( new Columns.All(), new Condition.Equals("deviceId", deviceId), - new Order(false, "id"), - new Limit(count))); + new Order("id", false, count))); for (var command : commands) { storage.removeObject(QueuedCommand.class, new Request( new Condition.Equals("id", command.getId()))); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 3722f2a22..994276bb6 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -30,7 +30,6 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; @@ -90,8 +89,7 @@ public class FilterHandler extends BaseDataHandler { new Condition.And( new Condition.Equals("deviceId", deviceId), new Condition.Compare("fixTime", "<=", "time", date)), - new Order(true, "fixTime"), - new Limit(1))); + new Order("fixTime", true, 1))); } private boolean filterInvalid(Position position) { diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 884c8fca8..a049a641c 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -24,7 +24,6 @@ import org.traccar.model.GroupedModel; import org.traccar.model.Permission; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; @@ -43,12 +42,19 @@ public class DatabaseStorage extends Storage { private final Config config; private final DataSource dataSource; private final ObjectMapper objectMapper; + private final String databaseType; @Inject public DatabaseStorage(Config config, DataSource dataSource, ObjectMapper objectMapper) { this.config = config; this.dataSource = dataSource; this.objectMapper = objectMapper; + + try { + databaseType = dataSource.getConnection().getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + throw new RuntimeException(e); + } } @Override @@ -62,7 +68,6 @@ public class DatabaseStorage extends Storage { query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); - query.append(formatLimit(request.getLimit())); try { QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { @@ -302,15 +307,16 @@ public class DatabaseStorage extends Storage { if (order.getDescending()) { result.append(" DESC"); } - } - return result.toString(); - } - - private String formatLimit(Limit limit) { - StringBuilder result = new StringBuilder(); - if (limit != null) { - result.append(" LIMIT "); - result.append(limit.getValue()); + if (order.getLimit() > 0) { + if (databaseType.equals("Microsoft SQL Server")) { + result.append(" OFFSET 0 ROWS FETCH FIRST "); + result.append(order.getLimit()); + result.append(" ROWS ONLY"); + } else { + result.append(" LIMIT "); + result.append(order.getLimit()); + } + } } return result.toString(); } diff --git a/src/main/java/org/traccar/storage/query/Order.java b/src/main/java/org/traccar/storage/query/Order.java index d12acc83b..b41f145e9 100644 --- a/src/main/java/org/traccar/storage/query/Order.java +++ b/src/main/java/org/traccar/storage/query/Order.java @@ -19,14 +19,16 @@ public class Order { private final String column; private final boolean descending; + private final int limit; public Order(String column) { - this(false, column); + this(column, false, 0); } - public Order(boolean descending, String column) { + public Order(String column, boolean descending, int limit) { this.column = column; - this.descending = descending; + this.descending = false; + this.limit = limit; } public String getColumn() { @@ -37,4 +39,8 @@ public class Order { return descending; } + public int getLimit() { + return limit; + } + } diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java index 41aa37bf1..6e9cecc63 100644 --- a/src/main/java/org/traccar/storage/query/Request.java +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -20,7 +20,6 @@ public class Request { private final Columns columns; private final Condition condition; private final Order order; - private final Limit limit; public Request(Columns columns) { this(columns, null, null); @@ -42,7 +41,6 @@ public class Request { this.columns = columns; this.condition = condition; this.order = order; - this.limit = limit; } public Columns getColumns() { @@ -57,8 +55,4 @@ public class Request { return order; } - public Limit getLimit() { - return limit; - } - } -- cgit v1.2.3 From db97378f2210818d0600420bc9c69103ddea248b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 16 Oct 2022 12:54:28 -0700 Subject: Improve Suntech support --- .../org/traccar/protocol/SuntechProtocolDecoder.java | 18 ++++++++++++++++-- .../org/traccar/protocol/SuntechProtocolEncoder.java | 10 +++++----- .../traccar/protocol/SuntechProtocolDecoderTest.java | 4 ++++ 3 files changed, 25 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index f1097abac..e67bd7a71 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -43,6 +43,7 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; +import java.util.stream.Collectors; public class SuntechProtocolDecoder extends BaseProtocolDecoder { @@ -203,12 +204,16 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_POWER_RESTORED; case 41: return Position.ALARM_POWER_CUT; + case 42: + return Position.ALARM_SOS; case 46: return Position.ALARM_ACCELERATION; case 47: return Position.ALARM_BRAKING; case 50: return Position.ALARM_JAMMING; + case 132: + return Position.ALARM_DOOR; default: return null; } @@ -468,7 +473,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { String type = values[index++]; - if (!type.equals("STT") && !type.equals("ALT") && !type.equals("BLE")) { + if (!type.equals("STT") && !type.equals("ALT") && !type.equals("BLE") && !type.equals("RES")) { return null; } @@ -481,6 +486,14 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_TYPE, type); + if (type.equals("RES")) { + getLastLocation(position, null); + position.set( + Position.KEY_RESULT, + Arrays.stream(values, index, values.length).collect(Collectors.joining(";"))); + return position; + } + int mask; if (type.equals("BLE")) { mask = 0b1100000110110; @@ -581,7 +594,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (type.equals("ALT")) { if (BitUtil.check(mask, 19)) { - position.set("alertId", values[index++]); + int alertId = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlert(alertId)); } if (BitUtil.check(mask, 20)) { position.set("alertModifier", values[index++]); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index 597acaae8..53308f968 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -45,13 +45,13 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { } if (universal) { - return encodeUniversalCommand(channel, command); + return encodeUniversalCommand(command); } else { - return encodeLegacyCommand(channel, prefix, command); + return encodeLegacyCommand(prefix, command); } } - protected Object encodeUniversalCommand(Channel channel, Command command) { + protected Object encodeUniversalCommand(Command command) { switch (command.getType()) { case Command.TYPE_REBOOT_DEVICE: return formatCommand(command, "CMD;%s;03;03\r", Command.KEY_UNIQUE_ID); @@ -84,7 +84,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_ENGINE_STOP: return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "CMD;%s;02;02\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_ARM: return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_DISARM: @@ -94,7 +94,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { } } - protected Object encodeLegacyCommand(Channel channel, String prefix, Command command) { + protected Object encodeLegacyCommand(String prefix, Command command) { switch (command.getType()) { case Command.TYPE_REBOOT_DEVICE: return formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 30959c8b9..ebd48c5c7 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -83,6 +83,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { var decoder = inject(new SuntechProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "RES;4309999001;04;02;TEST"), + Position.KEY_RESULT, "04;02;TEST"); + verifyPosition(decoder, buffer( "BLE;1140000053;114;1.0.1;20211001;17:27:09;+28.433465;-82.565891;1;-43;-46;-41;ACB89523EF68;247;0;0")); -- cgit v1.2.3 From dcecec13f6392980512e0ded566680c3dd657ab4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Oct 2022 16:54:56 -0700 Subject: Fix Suntech alert decoding --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index e67bd7a71..047a1822a 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -856,7 +856,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } else { - String[] values = buf.toString(StandardCharsets.US_ASCII).split(";"); + String[] values = buf.toString(StandardCharsets.US_ASCII).split(";", -1); prefix = values[0]; if (prefix.equals("CRR")) { diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index ebd48c5c7..e25ad124c 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -83,6 +83,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { var decoder = inject(new SuntechProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "ALT;0950030205;3FFFFF;95;1.0.11;0;20221017;21:41:30;02F2F402;334;20;0F1D;45;+25.791061;-100.170745;0.00;0.00;18;1;00000101;00000000;42;2;"), + Position.KEY_ALARM, Position.ALARM_SOS); + verifyAttribute(decoder, buffer( "RES;4309999001;04;02;TEST"), Position.KEY_RESULT, "04;02;TEST"); -- cgit v1.2.3 From 8f537de3bbf4dc1a742222dfd3123090b79e6419 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Oct 2022 09:24:25 -0700 Subject: Fix command queue issue --- schema/changelog-5.5.xml | 15 +++++++++++++++ schema/changelog-master.xml | 1 + src/main/java/org/traccar/model/BaseCommand.java | 10 ---------- src/main/java/org/traccar/model/Command.java | 10 ++++++++++ src/main/java/org/traccar/model/QueuedCommand.java | 5 +++-- 5 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 schema/changelog-5.5.xml (limited to 'src/main/java/org') diff --git a/schema/changelog-5.5.xml b/schema/changelog-5.5.xml new file mode 100644 index 000000000..4f5b210c5 --- /dev/null +++ b/schema/changelog-5.5.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index e877c1afd..cc39c5c41 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -35,5 +35,6 @@ + diff --git a/src/main/java/org/traccar/model/BaseCommand.java b/src/main/java/org/traccar/model/BaseCommand.java index 16df9c126..f87b8ef65 100644 --- a/src/main/java/org/traccar/model/BaseCommand.java +++ b/src/main/java/org/traccar/model/BaseCommand.java @@ -17,16 +17,6 @@ package org.traccar.model; public class BaseCommand extends Message { - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - private boolean textChannel; public boolean getTextChannel() { diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 4ea619e95..99988dd82 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -96,4 +96,14 @@ public class Command extends BaseCommand { super.setDeviceId(deviceId); } + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } diff --git a/src/main/java/org/traccar/model/QueuedCommand.java b/src/main/java/org/traccar/model/QueuedCommand.java index fff77a22b..96a1eca4b 100644 --- a/src/main/java/org/traccar/model/QueuedCommand.java +++ b/src/main/java/org/traccar/model/QueuedCommand.java @@ -15,18 +15,19 @@ */ package org.traccar.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.traccar.storage.StorageName; import java.util.HashMap; @StorageName("tc_commands_queue") +@JsonIgnoreProperties(ignoreUnknown = true) public class QueuedCommand extends BaseCommand { public static QueuedCommand fromCommand(Command command) { QueuedCommand queuedCommand = new QueuedCommand(); queuedCommand.setDeviceId(command.getDeviceId()); queuedCommand.setType(command.getType()); - queuedCommand.setDescription(command.getDescription()); queuedCommand.setTextChannel(command.getTextChannel()); queuedCommand.setAttributes(new HashMap<>(command.getAttributes())); return queuedCommand; @@ -36,7 +37,7 @@ public class QueuedCommand extends BaseCommand { Command command = new Command(); command.setDeviceId(getDeviceId()); command.setType(getType()); - command.setDescription(getDescription()); + command.setDescription(""); command.setTextChannel(getTextChannel()); command.setAttributes(new HashMap<>(getAttributes())); return command; -- cgit v1.2.3 From 73b174094effa2a2c9c3a076b5c244ba832a90c2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Oct 2022 05:54:29 -0700 Subject: Add Minifinder HDOP --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index bec05ffc2..f0ae28756 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -198,7 +198,9 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); position.setCourse(buf.readUnsignedShortLE()); position.setAltitude(buf.readShortLE()); - position.setValid(buf.readUnsignedShortLE() > 0); + int hdop = buf.readUnsignedShortLE(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop * 0.1); position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; -- cgit v1.2.3 From eef6c34d403fa5bf2ca0ae757792633c36052769 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Oct 2022 13:28:20 -0700 Subject: Update GPS103 command (fix #4964) --- src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java index e662e9b04..9a899eeeb 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java @@ -49,7 +49,7 @@ public class Gps103ProtocolEncoder extends StringProtocolEncoder implements Stri case Command.TYPE_CUSTOM: return formatCommand(command, "**,imei:%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA); case Command.TYPE_POSITION_STOP: - return formatCommand(command, "**,imei:%s,A", Command.KEY_UNIQUE_ID); + return formatCommand(command, "**,imei:%s,D", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "**,imei:%s,B", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_PERIODIC: -- cgit v1.2.3 From 8fe9e3f6ce857705fa609aa2728f73fdf98f3dbb Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Tue, 25 Oct 2022 11:06:27 +0800 Subject: Huabao Protocol: Add CC888 heartbeat packet From CC888 protocol When vehicle engine is OFF, the device will stop uploading location information to platform server, it will send heart beat message to platform server every 2 minutes, the heart beat message ID is 0x0506, the message body of heart beat message is empty. The platform will reply device with general replay message ID 0x8001 --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 27555d46d..cbaa6b9fd 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -51,6 +51,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GENERAL_RESPONSE = 0x8001; public static final int MSG_GENERAL_RESPONSE_2 = 0x4401; public static final int MSG_HEARTBEAT = 0x0002; + public static final int MSG_HEARTBEAT_2 = 0x0506; public static final int MSG_TERMINAL_REGISTER = 0x0100; public static final int MSG_TERMINAL_REGISTER_RESPONSE = 0x8100; public static final int MSG_TERMINAL_CONTROL = 0x8105; @@ -224,7 +225,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } - } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO) { + } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO || type == MSG_HEARTBEAT_2) { sendGeneralResponse(channel, remoteAddress, id, type, index); -- cgit v1.2.3 From fcdec06d0a6b9a742709de967b122ad6213637c1 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Wed, 26 Oct 2022 09:02:53 +0800 Subject: Huabao: code style - ordering Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index cbaa6b9fd..b6940aecf 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -225,7 +225,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } - } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO || type == MSG_HEARTBEAT_2) { + } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_HEARTBEAT_2 || type == MSG_PHOTO) { sendGeneralResponse(channel, remoteAddress, id, type, index); -- cgit v1.2.3 From 8ceb20c2d9c70f5e0aa107095a23c187019401f1 Mon Sep 17 00:00:00 2001 From: jcardus Date: Wed, 26 Oct 2022 14:48:31 +0100 Subject: 2 Bugs on maintenance According to the documentation: "Traccar can help control maintenance intervals of devices. There are two attributes to configure: maintenance.start and maintenance.interval. They can be set in device, group or server attributes. Traccar generates event every time totalDistance attribute gets over maintenance.start + maintenance.interval * N value where N is a natural number. Example: maintenance.start=6000000, maintenance.interval=8000000 Events will be generated when totalDistance goes over 6000 km, 14000 km, 22000 km and so on." In this example, the event won't be fired when it goes over 6000 km. If maintenance.interval < maintenance.start and maintenance.start is multiple of maintenance.interval then the event will be fired before maintenance.start because the comparison will be on negative numbers. Another solution would be to use absolute numbers on the comparison. Example: maintenance.start = 10 000 000 maintenance.interval = 2 000 000 the event will be fired when it goes over 2 000 000 the event wont' be fired when it goes over 10 000 000 --- .../traccar/handler/events/MaintenanceEventHandler.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 4fcfcd079..25a622373 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -51,13 +51,15 @@ public class MaintenanceEventHandler extends BaseEventHandler { if (maintenance.getPeriod() != 0) { double oldValue = lastPosition.getDouble(maintenance.getType()); double newValue = position.getDouble(maintenance.getType()); - if (oldValue != 0.0 && newValue != 0.0 - && (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) + if (oldValue != 0.0 && newValue != 0.0 && newValue >= maintenance.getStart()) { + if (oldValue < maintenance.getStart() + || (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { - Event event = new Event(Event.TYPE_MAINTENANCE, position); - event.setMaintenanceId(maintenance.getId()); - event.set(maintenance.getType(), newValue); - events.put(event, position); + Event event = new Event(Event.TYPE_MAINTENANCE, position); + event.setMaintenanceId(maintenance.getId()); + event.set(maintenance.getType(), newValue); + events.put(event, position); + } } } } -- cgit v1.2.3 From 3c7afdf75c4f3d045c0d51355d6ce62622eb2c4d Mon Sep 17 00:00:00 2001 From: jcardus Date: Wed, 26 Oct 2022 15:02:22 +0100 Subject: Update MaintenanceEventHandler.java trailing spaces --- src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 25a622373..909950acf 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -52,7 +52,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { double oldValue = lastPosition.getDouble(maintenance.getType()); double newValue = position.getDouble(maintenance.getType()); if (oldValue != 0.0 && newValue != 0.0 && newValue >= maintenance.getStart()) { - if (oldValue < maintenance.getStart() + if (oldValue < maintenance.getStart() || (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { Event event = new Event(Event.TYPE_MAINTENANCE, position); -- cgit v1.2.3 From cf59eb2c734f7d8bd5ea8f9ff82d4dc91492693f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 26 Oct 2022 21:51:15 -0700 Subject: Remove duplicate token --- src/main/java/org/traccar/api/resource/PasswordResource.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index ebf4e3b91..2d87a8665 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -62,7 +62,6 @@ public class PasswordResource extends BaseResource { new Columns.All(), new Condition.Equals("email", email))); if (user != null) { var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", tokenManager.generateToken(user.getId())); var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } -- cgit v1.2.3 From ab10e710a9c57ef761ea9955198273db5f473581 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 27 Oct 2022 07:17:25 -0700 Subject: Fix DT700 temperature decoding --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 15 +++++++++------ .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index b6940aecf..27a5094a0 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -408,6 +408,13 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } } + private double decodeCustomDouble(ByteBuf buf) { + int b1 = buf.readByte(); + int b2 = buf.readUnsignedByte(); + int sign = b1 != 0 ? b1 / Math.abs(b1) : 1; + return sign * (Math.abs(b1) + b2 / 255.0); + } + private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { Position position = new Position(getProtocolName()); @@ -529,12 +536,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { while (buf.readerIndex() < endIndex) { int sensorIndex = buf.readUnsignedByte(); buf.skipBytes(6); // mac - position.set( - Position.PREFIX_TEMP + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); - position.set( - "humidity" + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set(Position.PREFIX_TEMP + sensorIndex, decodeCustomDouble(buf)); + position.set("humidity" + sensorIndex, decodeCustomDouble(buf)); } break; case 0xEB: diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index f7873ef08..9bbd375dc 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -15,8 +15,8 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); verifyAttribute(decoder, binary( - "7e0200005e01229130231209e300000000000c002300d264a305ff322300160000000022091514493503020000a70400000000ac0400000000e5020003e62c01bc5729009ca319bbff0002dd34020754fe1a83393c03bc572900ce371a6133d704dd34020751551d00fefb9a7e"), - Position.PREFIX_TEMP + 4, 29.0); + "7e02000042012291302260198f00000000800c012300d2651605ff3188001e0000000022102510310003020000a70400000000ac040000012ce5020003e60b03bc572900ce2eef183200e7030000005c7e"), + Position.PREFIX_TEMP + 3, -17.094117647058823); verifyAttribute(decoder, binary( "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), -- cgit v1.2.3 From c59ba066b1437e98af10a413b9e0c29f0e443b26 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 27 Oct 2022 17:56:32 -0700 Subject: Support Teltonika DualCam video --- .../traccar/protocol/DualcamProtocolDecoder.java | 36 ++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index c5835bc7d..e646c4e4a 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.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. @@ -46,7 +46,8 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { private String uniqueId; private int packetCount; private int currentPacket; - private ByteBuf photo; + private boolean video; + private ByteBuf media; @Override protected Object decode( @@ -64,9 +65,22 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { long settings = buf.readUnsignedInt(); if (channel != null && deviceSession != null) { ByteBuf response = Unpooled.buffer(); - if (BitUtil.between(settings, 26, 28) > 0) { + if (BitUtil.between(settings, 26, 30) > 0) { response.writeShort(MSG_FILE_REQUEST); - String file = BitUtil.check(settings, 26) ? "%photof" : "%photor"; + String file; + if (BitUtil.check(settings, 26)) { + video = false; + file = "%photof"; + } else if (BitUtil.check(settings, 27)) { + video = false; + file = "%photor"; + } else if (BitUtil.check(settings, 28)) { + video = true; + file = "%videof"; + } else { + video = true; + file = "%videor"; + } response.writeShort(file.length()); response.writeCharSequence(file, StandardCharsets.US_ASCII); } else { @@ -79,7 +93,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // length packetCount = buf.readInt(); currentPacket = 1; - photo = Unpooled.buffer(); + media = Unpooled.buffer(); if (channel != null) { ByteBuf response = Unpooled.buffer(); response.writeShort(MSG_RESUME); @@ -90,17 +104,21 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { break; case MSG_DATA: buf.readUnsignedShort(); // length - photo.writeBytes(buf, buf.readableBytes() - 2); + media.writeBytes(buf, buf.readableBytes() - 2); if (currentPacket == packetCount) { deviceSession = getDeviceSession(channel, remoteAddress); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + if (video) { + position.set(Position.KEY_VIDEO, writeMediaFile(uniqueId, media, "h265")); + } else { + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, media, "jpg")); + } } finally { - photo.release(); - photo = null; + media.release(); + media = null; } if (channel != null) { ByteBuf response = Unpooled.buffer(); -- cgit v1.2.3 From 0508411fc388d8a7495b43378cfa6265a24c02d2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 28 Oct 2022 05:05:18 -0700 Subject: Missing iStartek parameters --- .../java/org/traccar/protocol/StartekProtocolDecoder.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index b2fcd5452..8e3624cb5 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -83,9 +83,9 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .groupBegin() .number("(d+)?|") // rpm .number("(d+)?|") // engine load - .number("d*|") // maf flow - .number("d*|") // intake pressure - .number("d*|") // intake temperature + .number("(d+)?|") // maf flow + .number("(d+)?|") // intake pressure + .number("(d+)?|") // intake temperature .number("(d+)?|") // throttle .number("(d+)?|") // coolant temperature .number("(d+)?|") // instant fuel @@ -224,6 +224,11 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(6)) { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); + position.set("airFlow", parser.nextInt()); + position.set("airPressure", parser.nextInt()); + if (parser.hasNext()) { + position.set("airTemp", parser.nextInt() - 40); + } position.set(Position.KEY_THROTTLE, parser.nextInt()); if (parser.hasNext()) { position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); -- cgit v1.2.3 From 87d54329d8d6ba14f37e15967079bcfc7299228c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 28 Oct 2022 06:08:10 -0700 Subject: Address in events report (fix #4761) --- .../org/traccar/reports/EventsReportProvider.java | 11 +++++++++++ templates/export/events.xlsx | Bin 8763 -> 9023 bytes 2 files changed, 11 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index d0d4fe8bf..30f55ba80 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -24,6 +24,7 @@ import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; +import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; @@ -102,6 +103,7 @@ public class EventsReportProvider { ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); + HashMap positions = new HashMap<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); @@ -129,6 +131,14 @@ public class EventsReportProvider { iterator.remove(); } } + for (Event event : events) { + long positionId = event.getPositionId(); + if (positionId > 0) { + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", positionId))); + positions.put(positionId, position); + } + } DeviceReportSection deviceEvents = new DeviceReportSection(); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); @@ -150,6 +160,7 @@ public class EventsReportProvider { context.putVar("sheetNames", sheetNames); context.putVar("geofenceNames", geofenceNames); context.putVar("maintenanceNames", maintenanceNames); + context.putVar("positions", positions); context.putVar("from", from); context.putVar("to", to); reportUtils.processTemplateWithSheets(inputStream, outputStream, context); diff --git a/templates/export/events.xlsx b/templates/export/events.xlsx index a6366750c..d0120ab8e 100644 Binary files a/templates/export/events.xlsx and b/templates/export/events.xlsx differ -- cgit v1.2.3 From d5ac6aa371b5dfd9a6613e693a6afc711fb740df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Nov 2022 17:06:51 -0700 Subject: Improve permission check --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 0d4877fdb..71acb3d48 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -104,7 +104,7 @@ public class PermissionsService { } else if (clazz.equals(Device.class)) { denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly() || addition && getUser(userId).getDeviceLimit() == 0; - if (addition && getUser(userId).getDeviceLimit() > 0) { + if (!denied && addition && getUser(userId).getDeviceLimit() > 0) { int deviceCount = storage.getObjects(Device.class, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))).size(); -- cgit v1.2.3 From 49646eccd5ec57013c78ea0a0776c206f812cb0b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Nov 2022 21:26:02 -0700 Subject: Better Meiligao commands --- .../org/traccar/protocol/MeiligaoProtocol.java | 1 + .../traccar/protocol/MeiligaoProtocolEncoder.java | 47 +++++++++++++++++----- .../protocol/MeiligaoProtocolEncoderTest.java | 4 ++ 3 files changed, 41 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index 2c853f0e1..492094ce3 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -30,6 +30,7 @@ public class MeiligaoProtocol extends BaseProtocol { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, + Command.TYPE_OUTPUT_CONTROL, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_GEOFENCE, diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index 21f9f8801..03f0e7ecf 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -24,8 +24,10 @@ import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.model.Device; import java.nio.charset.StandardCharsets; +import java.util.Set; import java.util.TimeZone; public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @@ -57,15 +59,36 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { return buf; } - @Override - protected Object encodeCommand(Command command) { + private ByteBuf encodeOutputCommand(long deviceId, int index, int value) { + + int outputCount; + int outputType; + + String model = getCacheManager().getObject(Device.class, deviceId).getModel(); - boolean alternative = AttributeUtil.lookup( - getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); + if (model != null && Set.of("TK510", "GT08", "TK208", "TK228", "MT05").contains(model)) { + outputCount = 5; + outputType = MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1; + } else { + outputCount = 1; + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), deviceId); + outputType = alternative + ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 + : MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_2; + } + + ByteBuf content = Unpooled.buffer(); - int outputControlMessageType = alternative - ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 - : MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_2; + for (int i = 1; i <= outputCount; i++) { + content.writeByte(i == index ? value : 2); + } + + return encodeContent(deviceId, outputType, content); + } + + @Override + protected Object encodeCommand(Command command) { ByteBuf content = Unpooled.buffer(); @@ -75,12 +98,14 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { case Command.TYPE_POSITION_PERIODIC: content.writeShort(command.getInteger(Command.KEY_FREQUENCY) / 10); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TRACK_BY_INTERVAL, content); + case Command.TYPE_OUTPUT_CONTROL: + int index = Integer.parseInt(command.getString(Command.KEY_INDEX)) - 1; + int value = Integer.parseInt(command.getString(Command.KEY_DATA)); + return encodeOutputCommand(command.getDeviceId(), index, value); case Command.TYPE_ENGINE_STOP: - content.writeByte(0x01); - return encodeContent(command.getDeviceId(), outputControlMessageType, content); + return encodeOutputCommand(command.getDeviceId(), 1, 1); case Command.TYPE_ENGINE_RESUME: - content.writeByte(0x00); - return encodeContent(command.getDeviceId(), outputControlMessageType, content); + return encodeOutputCommand(command.getDeviceId(), 1, 0); case Command.TYPE_ALARM_GEOFENCE: content.writeShort(command.getInteger(Command.KEY_RADIUS)); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_MOVEMENT_ALARM, content); diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java index 5b72f6f1f..1f2e5f7e3 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java @@ -36,6 +36,10 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { verifyCommand(encoder, command, binary("4040001312345678901234410603e87bb00d0a")); + command.setType(Command.TYPE_ENGINE_STOP); + + verifyCommand(encoder, command, binary("4040001212345678901234411501fd460d0a")); + } } -- cgit v1.2.3 From 9280355123ee13f7f7d8bf7076a39dcab57ab1cd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Nov 2022 17:57:22 -0700 Subject: Improve attribute type handling --- src/main/java/org/traccar/model/ExtendedModel.java | 30 ++++++++++++++++++---- .../org/traccar/protocol/KhdProtocolEncoder.java | 2 +- .../traccar/protocol/MeiligaoProtocolEncoder.java | 6 ++--- .../traccar/protocol/RuptelaProtocolEncoder.java | 4 +-- .../traccar/protocol/SuntechProtocolEncoder.java | 16 ++++++------ 5 files changed, 39 insertions(+), 19 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index ef2e3b68f..7a61eda8c 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -91,7 +91,7 @@ public class ExtendedModel extends BaseModel { public String getString(String key) { if (attributes.containsKey(key)) { - return (String) attributes.get(key); + return attributes.get(key).toString(); } else { return null; } @@ -99,7 +99,12 @@ public class ExtendedModel extends BaseModel { public double getDouble(String key) { if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).doubleValue(); + Object value = attributes.get(key); + if (value instanceof Number) { + return ((Number) attributes.get(key)).doubleValue(); + } else { + return Double.parseDouble(value.toString()); + } } else { return 0.0; } @@ -107,7 +112,12 @@ public class ExtendedModel extends BaseModel { public boolean getBoolean(String key) { if (attributes.containsKey(key)) { - return (Boolean) attributes.get(key); + Object value = attributes.get(key); + if (value instanceof Boolean) { + return (Boolean) attributes.get(key); + } else { + return Boolean.parseBoolean(value.toString()); + } } else { return false; } @@ -115,7 +125,12 @@ public class ExtendedModel extends BaseModel { public int getInteger(String key) { if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).intValue(); + Object value = attributes.get(key); + if (value instanceof Number) { + return ((Number) attributes.get(key)).intValue(); + } else { + return Integer.parseInt(value.toString()); + } } else { return 0; } @@ -123,7 +138,12 @@ public class ExtendedModel extends BaseModel { public long getLong(String key) { if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).longValue(); + Object value = attributes.get(key); + if (value instanceof Number) { + return ((Number) attributes.get(key)).longValue(); + } else { + return Long.parseLong(value.toString()); + } } else { return 0; } diff --git a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java index 8aeb9660d..12353b415 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java @@ -84,7 +84,7 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder { return encodeCommand(MSG_FACTORY_RESET, uniqueId, null); case Command.TYPE_SET_SPEED_LIMIT: ByteBuf content = Unpooled.buffer(); - content.writeByte(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeByte(command.getInteger(Command.KEY_DATA)); return encodeCommand(MSG_RESUME_OIL, uniqueId, content); case Command.TYPE_SET_ODOMETER: return encodeCommand(MSG_DELETE_MILEAGE, uniqueId, null); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index 03f0e7ecf..5859d91ce 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.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. @@ -99,8 +99,8 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { content.writeShort(command.getInteger(Command.KEY_FREQUENCY) / 10); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TRACK_BY_INTERVAL, content); case Command.TYPE_OUTPUT_CONTROL: - int index = Integer.parseInt(command.getString(Command.KEY_INDEX)) - 1; - int value = Integer.parseInt(command.getString(Command.KEY_DATA)); + int index = command.getInteger(Command.KEY_INDEX) - 1; + int value = command.getInteger(Command.KEY_DATA); return encodeOutputCommand(command.getDeviceId(), index, value); case Command.TYPE_ENGINE_STOP: return encodeOutputCommand(command.getDeviceId(), 1, 1); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java index 442961b19..5ec971a98 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java @@ -80,14 +80,14 @@ public class RuptelaProtocolEncoder extends BaseProtocolEncoder { return encodeContent(RuptelaProtocolDecoder.MSG_FIRMWARE_UPDATE, content); case Command.TYPE_OUTPUT_CONTROL: content.writeInt(command.getInteger(Command.KEY_INDEX)); - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeInt(command.getInteger(Command.KEY_DATA)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_IO, content); case Command.TYPE_SET_CONNECTION: String c = command.getString(Command.KEY_SERVER) + "," + command.getInteger(Command.KEY_PORT) + ",TCP"; content.writeBytes(c.getBytes(StandardCharsets.US_ASCII)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_CONNECTION, content); case Command.TYPE_SET_ODOMETER: - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeInt(command.getInteger(Command.KEY_DATA)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_ODOMETER, content); default: return null; diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index 53308f968..b298adc5a 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -59,23 +59,23 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { return formatCommand(command, "CMD;%s;03;01\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { - switch (command.getString(Command.KEY_INDEX)) { - case "1": + switch (command.getInteger(Command.KEY_INDEX)) { + case 1: return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); - case "2": + case 2: return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); - case "3": + case 3: return formatCommand(command, "CMD;%s;04;09\r", Command.KEY_UNIQUE_ID); default: return null; } } else { - switch (command.getString(Command.KEY_INDEX)) { - case "1": + switch (command.getInteger(Command.KEY_INDEX)) { + case 1: return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); - case "2": + case 2: return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); - case "3": + case 3: return formatCommand(command, "CMD;%s;04;10\r", Command.KEY_UNIQUE_ID); default: return null; -- cgit v1.2.3 From 9c03a0505f46a92f645dc927dba2da6458facfb1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Nov 2022 20:29:36 -0700 Subject: Reuse checksum code --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 8a58ebc5e..8e5269ec8 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -363,17 +363,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - if (channel != null) { + if (channel == null) { StringBuilder command = new StringBuilder("@@"); command.append(flag).append(27 + positions.size() / 10).append(","); command.append(imei).append(",CCC,").append(positions.size()).append("*"); - int checksum = 0; - for (int i = 0; i < command.length(); i += 1) { - checksum += command.charAt(i); - } - command.append(String.format("%02x", checksum & 0xff).toUpperCase()); + command.append(Checksum.sum(command.toString())); command.append("\r\n"); - channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); // delete processed data + channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); } return positions; -- cgit v1.2.3 From fdd52edc7811ae973c93ae825cc1bd1d9e9fe33f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Nov 2022 20:30:00 -0700 Subject: Fix response --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 8e5269ec8..736f5871c 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -363,7 +363,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - if (channel == null) { + if (channel != null) { StringBuilder command = new StringBuilder("@@"); command.append(flag).append(27 + positions.size() / 10).append(","); command.append(imei).append(",CCC,").append(positions.size()).append("*"); -- cgit v1.2.3 From e742f252da0b32ac7166c6d9ab25a8d1375411d2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Nov 2022 20:36:25 -0700 Subject: Add MD500S heartbeat response --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 13 ++++++++++--- .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 736f5871c..1935b2c2a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -538,13 +538,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { return positions; } - private void requestPhotoPacket(Channel channel, SocketAddress socketAddress, String imei, String file, int index) { + private void requestPhotoPacket(Channel channel, SocketAddress remoteAddress, String imei, String file, int index) { if (channel != null) { String content = "D00," + file + "," + index; int length = 1 + imei.length() + 1 + content.length() + 5; String response = String.format("@@O%02d,%s,%s*", length, imei, content); response += Checksum.sum(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, socketAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } @@ -560,6 +560,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { String type = buf.toString(index + 1, 3, StandardCharsets.US_ASCII); switch (type) { + case "AAC": + if (channel != null) { + String response = String.format("@@z27,%s,AAC,1*", imei); + response += Checksum.sum(response) + "\r\n"; + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + return null; case "D00": if (photo == null) { photo = Unpooled.buffer(); diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 0fc51b8b6..67b83ebd9 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -129,6 +129,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "2424473937302c3336393830303031333436303637342c4343432c020134005b000000010ce304035db9e000ec6f591a000013000000000c001801edb70200c96d0100e60001004838576501000300a101c20400000000010ce304035db9e000ee6f591a000013000000000c001801edb70200ca6d0100e60001004838576501000300a101c20400000000010ce304035db9e000ef6f591a000013000000000c001801edb70200cc6d0100e60001004838576501000300a101c20400000000020ce304035db9e000f76f591a000016000000000c001801edb70200d36d0100e60001004838576502000300a101bf04000000000a0ce304035db9e000f76f591a000016000000000c001801edb70200d46d0100e60001004838576500000300a101bf0400000000020ce304035db9e000fb6f591a000016000000000c001801edb70200d86d0100e60001004838576502000300a101760400000000180ce304035db9e000fc6f591a0000120000000000008c00edb70200d96d0100e60001004838576502000300a10176040000000019b1e2040323b9e0000b70591a0105150600bb0012002901edb70200e76d0100e60001004838576502000300a2017005000000002023e304031fb9e0001070591a010615070027010d001601fcb70200ec6d0100e60001004838576502000300a201800500000000201fe3040302b9e0001170591a010615090019010d001501feb70200ed6d0100e60001004838576502000300a2018005000000002018e30403dcb8e0001270591a0106150b0011010d00150100b80200ee6d0100e60001004838576502000300a2018005000000002036e3040345b8e0001570591a0107150b002d010b0013010ab80200f16d0100e60001004838576502000300a2018005000000002053e3040326b8e0001670591a0107150d0041010b0013010eb80200f26d0100e60001004838576502000300a2018005000000002070e3040310b8e0001770591a0107150e004f010b00130111b80200f36d0100e60001004838576502000300a2018005000000002095e3040306b8e0001870591a0107150d005a010b00140115b80200f46d0100e60001004838576502000300a20180050000000020b3e3040305b8e0001970591a0107150b0060010b00140118b80200f56d0100e60001004838576502000300a20183050000000020cfe3040308b8e0001a70591a0107150b0066010b0014011bb80200f66d0100e60001004838576502000300a20183050000000020eee304030cb8e0001b70591a0106170b0004000d0014011eb80200f76d0100e60001004838576502000300a2018305000000002a62350d0a")); + verifyNull(decoder, buffer( + "$$z27,861451040910625,AAC,1*D3")); + } } -- cgit v1.2.3 From 21a916159a24db0cbec850b90381f9ff392f3c0e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Nov 2022 08:55:31 -0700 Subject: Clean up command resource --- src/main/java/org/traccar/api/resource/CommandResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 80b9fd18f..6ef6ee9c5 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -84,10 +84,10 @@ public class CommandResource extends ExtendedObjectResource { permissionsService.checkPermission(Device.class, getUserId(), deviceId); BaseProtocol protocol = getDeviceProtocol(deviceId); - var commands = storage.getObjects(Command.class, new Request( + var commands = storage.getObjects(baseClass, new Request( new Columns.All(), Condition.merge(List.of( - new Condition.Permission(User.class, getUserId(), Command.class), + new Condition.Permission(User.class, getUserId(), baseClass), new Condition.Permission(Device.class, deviceId, baseClass) )))); @@ -107,7 +107,7 @@ public class CommandResource extends ExtendedObjectResource { public Response send(Command entity) throws Exception { permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); if (entity.getId() > 0) { - permissionsService.checkPermission(Command.class, getUserId(), entity.getId()); + permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); long deviceId = entity.getDeviceId(); entity = storage.getObject(baseClass, new Request( new Columns.All(), new Condition.Equals("id", entity.getId()))); -- cgit v1.2.3 From d0df0c2e33034efee4a3a0705c92b09dbed5e291 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Nov 2022 10:01:50 -0800 Subject: Handle missing cache --- .../org/traccar/session/cache/CacheManager.java | 24 +++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 8f2e7ba93..dc7382223 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,8 @@ */ package org.traccar.session.cache; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastInterface; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; @@ -42,6 +44,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -57,6 +60,7 @@ import java.util.stream.Collectors; @Singleton public class CacheManager implements BroadcastInterface { + private static final Logger LOGGER = LoggerFactory.getLogger(CacheManager.class); private static final int GROUP_DEPTH_LIMIT = 3; private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); @@ -102,13 +106,19 @@ public class CacheManager implements BroadcastInterface { public List getDeviceObjects(long deviceId, Class clazz) { try { lock.readLock().lock(); - return deviceLinks.get(deviceId).get(clazz).stream() - .map(id -> { - var cacheValue = deviceCache.get(new CacheKey(clazz, id)); - return cacheValue != null ? cacheValue.getValue() : null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + var links = deviceLinks.get(deviceId); + if (links != null) { + return links.getOrDefault(clazz, new LinkedHashSet<>()).stream() + .map(id -> { + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + return cacheValue != null ? cacheValue.getValue() : null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } else { + LOGGER.warn("Device {} cache missing", deviceId); + return Collections.emptyList(); + } } finally { lock.readLock().unlock(); } -- cgit v1.2.3 From d9d990b492896d7e42a503c002de7715f6d12a30 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Nov 2022 08:29:10 -0800 Subject: Add comment --- src/main/java/org/traccar/WebDataHandler.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 9b26c8875..2d2e3dc8f 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -126,6 +126,7 @@ public class WebDataHandler extends BaseDataHandler { return s.toString(); } + // OpenGTS status code private String calculateStatus(Position position) { if (position.hasAttribute(Position.KEY_ALARM)) { return "0xF841"; // STATUS_PANIC_ON -- cgit v1.2.3 From 4ec9db613475066de3f46c24d4ee78fefcbb17df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 09:19:16 -0800 Subject: Fix manager permission (fix #4982) --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 71acb3d48..37bb6fd72 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -34,6 +34,7 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import java.util.Objects; @RequestScoped public class PermissionsService { @@ -158,6 +159,7 @@ public class PermissionsService { } User user = getUser(userId); if (user != null && user.getExpirationTime() != null + && !Objects.equals(before.getExpirationTime(), after.getExpirationTime()) && (after.getExpirationTime() == null || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { checkAdmin(userId); -- cgit v1.2.3 From ff793b2e2872f8ba076e748fab41d944f92b64d4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 10:12:32 -0800 Subject: Refactor event forwarding --- src/main/java/org/traccar/MainModule.java | 7 +- .../org/traccar/database/NotificationManager.java | 20 +++- src/main/java/org/traccar/forward/EventData.java | 78 +++++++++++++++ .../java/org/traccar/forward/EventForwarder.java | 20 ++++ .../org/traccar/forward/EventForwarderJson.java | 66 +++++++++++++ .../org/traccar/notification/EventForwarder.java | 109 --------------------- 6 files changed, 186 insertions(+), 114 deletions(-) create mode 100644 src/main/java/org/traccar/forward/EventData.java create mode 100644 src/main/java/org/traccar/forward/EventForwarder.java create mode 100644 src/main/java/org/traccar/forward/EventForwarderJson.java delete mode 100644 src/main/java/org/traccar/notification/EventForwarder.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index c4cda578e..9a5cca4c7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -35,6 +35,8 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; +import org.traccar.forward.EventForwarder; +import org.traccar.forward.EventForwarderJson; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; @@ -67,7 +69,6 @@ import org.traccar.helper.SanitizerModule; import org.traccar.mail.LogMailManager; import org.traccar.mail.MailManager; import org.traccar.mail.SmtpMailManager; -import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; @@ -310,9 +311,9 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static EventForwarder provideEventForwarder(Config config, Client client, CacheManager cacheManager) { + public static EventForwarder provideEventForwarder(Config config, Client client) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarder(config, client, cacheManager); + return new EventForwarderJson(config, client); } return null; } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 5ea89fcac..7c82454b2 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -20,12 +20,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.forward.EventData; +import org.traccar.forward.EventForwarder; import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; -import org.traccar.notification.EventForwarder; import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; @@ -112,8 +115,21 @@ public class NotificationManager { }); } + forwardEvent(event, position); + } + + private void forwardEvent(Event event, Position position) { if (eventForwarder != null) { - eventForwarder.forwardEvent(event, position); + EventData eventData = new EventData(); + eventData.setEvent(event); + eventData.setPosition(position); + if (event.getGeofenceId() != 0) { + eventData.setGeofence(cacheManager.getObject(Geofence.class, event.getGeofenceId())); + } + if (event.getMaintenanceId() != 0) { + eventData.setMaintenance(cacheManager.getObject(Maintenance.class, event.getMaintenanceId())); + } + eventForwarder.forward(eventData); } } diff --git a/src/main/java/org/traccar/forward/EventData.java b/src/main/java/org/traccar/forward/EventData.java new file mode 100644 index 000000000..4471b10b3 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventData.java @@ -0,0 +1,78 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.annotation.JsonInclude; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; +import org.traccar.model.Position; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class EventData { + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + + private Position position; + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + + private Device device; + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } + + private Geofence geofence; + + public Geofence getGeofence() { + return geofence; + } + + public void setGeofence(Geofence geofence) { + this.geofence = geofence; + } + + private Maintenance maintenance; + + public Maintenance getMaintenance() { + return maintenance; + } + + public void setMaintenance(Maintenance maintenance) { + this.maintenance = maintenance; + } + +} diff --git a/src/main/java/org/traccar/forward/EventForwarder.java b/src/main/java/org/traccar/forward/EventForwarder.java new file mode 100644 index 000000000..c3ad5efc0 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarder.java @@ -0,0 +1,20 @@ +/* + * 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.forward; + +public interface EventForwarder { + void forward(EventData eventData); +} diff --git a/src/main/java/org/traccar/forward/EventForwarderJson.java b/src/main/java/org/traccar/forward/EventForwarderJson.java new file mode 100644 index 000000000..c136fd4e2 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarderJson.java @@ -0,0 +1,66 @@ +/* + * 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.forward; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.InvocationCallback; + +public class EventForwarderJson implements EventForwarder { + + private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarderJson.class); + + private final String url; + private final String header; + + private final Client client; + + @Inject + public EventForwarderJson(Config config, Client client) { + this.client = client; + url = config.getString(Keys.EVENT_FORWARD_URL); + header = config.getString(Keys.EVENT_FORWARD_HEADERS); + } + + public void forward(EventData eventData) { + var requestBuilder = client.target(url).request(); + + if (header != null && !header.isEmpty()) { + for (String line: header.split("\\r?\\n")) { + String[] values = line.split(":", 2); + requestBuilder.header(values[0].trim(), values[1].trim()); + } + } + + requestBuilder.async().post(Entity.json(eventData), new InvocationCallback<>() { + @Override + public void completed(Object o) { + } + + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Event forwarding failed", throwable); + } + }); + } + +} diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java deleted file mode 100644 index 50f17a852..000000000 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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. - * 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.notification; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Geofence; -import org.traccar.model.Maintenance; -import org.traccar.model.Position; -import org.traccar.session.cache.CacheManager; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.InvocationCallback; -import java.util.HashMap; -import java.util.Map; - -public class EventForwarder { - - private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarder.class); - - private final String url; - private final String header; - - private final Client client; - private final CacheManager cacheManager; - - public EventForwarder(Config config, Client client, CacheManager cacheManager) { - this.client = client; - this.cacheManager = cacheManager; - url = config.getString(Keys.EVENT_FORWARD_URL); - header = config.getString(Keys.EVENT_FORWARD_HEADERS); - } - - private static final String KEY_POSITION = "position"; - private static final String KEY_EVENT = "event"; - private static final String KEY_GEOFENCE = "geofence"; - private static final String KEY_DEVICE = "device"; - private static final String KEY_MAINTENANCE = "maintenance"; - - public final void forwardEvent(Event event, Position position) { - - Invocation.Builder requestBuilder = client.target(url).request(); - - if (header != null && !header.isEmpty()) { - for (String line: header.split("\\r?\\n")) { - String[] values = line.split(":", 2); - requestBuilder.header(values[0].trim(), values[1].trim()); - } - } - - LOGGER.debug("Event forwarding initiated"); - requestBuilder.async().post(Entity.json(preparePayload(event, position)), new InvocationCallback<>() { - @Override - public void completed(Object o) { - LOGGER.debug("Event forwarding succeeded"); - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Event forwarding failed", throwable); - } - }); - } - - protected Map preparePayload(Event event, Position position) { - Map data = new HashMap<>(); - data.put(KEY_EVENT, event); - if (position != null) { - data.put(KEY_POSITION, position); - } - Device device = cacheManager.getObject(Device.class, event.getDeviceId()); - if (device != null) { - data.put(KEY_DEVICE, device); - } - if (event.getGeofenceId() != 0) { - Geofence geofence = cacheManager.getObject(Geofence.class, event.getGeofenceId()); - if (geofence != null) { - data.put(KEY_GEOFENCE, geofence); - } - } - if (event.getMaintenanceId() != 0) { - Maintenance maintenance = cacheManager.getObject(Maintenance.class, event.getMaintenanceId()); - if (maintenance != null) { - data.put(KEY_MAINTENANCE, maintenance); - } - } - return data; - } - -} -- cgit v1.2.3 From 5877cb1b3f1fa7331c4310b9754a3ec442586497 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 11:48:43 -0800 Subject: Refactor position forwarding --- src/main/java/org/traccar/BasePipelineFactory.java | 2 +- src/main/java/org/traccar/MainModule.java | 16 ++ .../org/traccar/PositionForwardingHandler.java | 141 +++++++++ src/main/java/org/traccar/WebDataHandler.java | 316 --------------------- src/main/java/org/traccar/config/Keys.java | 17 +- .../org/traccar/database/NotificationManager.java | 6 +- .../java/org/traccar/forward/EventForwarder.java | 2 +- .../org/traccar/forward/EventForwarderJson.java | 22 +- .../java/org/traccar/forward/PositionData.java | 45 +++ .../org/traccar/forward/PositionForwarder.java | 20 ++ .../org/traccar/forward/PositionForwarderJson.java | 86 ++++++ .../org/traccar/forward/PositionForwarderUrl.java | 166 +++++++++++ .../java/org/traccar/forward/ResultHandler.java | 20 ++ src/test/java/org/traccar/WebDataHandlerTest.java | 42 --- .../traccar/forward/PositionForwarderUrlTest.java | 42 +++ 15 files changed, 561 insertions(+), 382 deletions(-) create mode 100644 src/main/java/org/traccar/PositionForwardingHandler.java delete mode 100644 src/main/java/org/traccar/WebDataHandler.java create mode 100644 src/main/java/org/traccar/forward/PositionData.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarder.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarderJson.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarderUrl.java create mode 100644 src/main/java/org/traccar/forward/ResultHandler.java delete mode 100644 src/test/java/org/traccar/WebDataHandlerTest.java create mode 100644 src/test/java/org/traccar/forward/PositionForwarderUrlTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 0d91ec7e4..b184da45c 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -140,7 +140,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { CopyAttributesHandler.class, EngineHoursHandler.class, ComputedAttributesHandler.class, - WebDataHandler.class, + PositionForwardingHandler.class, DefaultDataHandler.class, MediaEventHandler.class, CommandResultEventHandler.class, diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 9a5cca4c7..9d450fef7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -37,6 +37,9 @@ import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; +import org.traccar.forward.PositionForwarder; +import org.traccar.forward.PositionForwarderJson; +import org.traccar.forward.PositionForwarderUrl; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; @@ -318,6 +321,19 @@ public class MainModule extends AbstractModule { return null; } + @Singleton + @Provides + public static PositionForwarder providePositionForwarder(Config config, Client client, ObjectMapper objectMapper) { + if (config.hasKey(Keys.FORWARD_URL)) { + if (config.getBoolean(Keys.FORWARD_JSON)) { + return new PositionForwarderJson(config, client, objectMapper); + } else { + return new PositionForwarderUrl(config, client, objectMapper); + } + } + return null; + } + @Singleton @Provides public static VelocityEngine provideVelocityEngine(Config config) { diff --git a/src/main/java/org/traccar/PositionForwardingHandler.java b/src/main/java/org/traccar/PositionForwardingHandler.java new file mode 100644 index 000000000..83f91e937 --- /dev/null +++ b/src/main/java/org/traccar/PositionForwardingHandler.java @@ -0,0 +1,141 @@ +/* + * 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. + * 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; + +import io.netty.channel.ChannelHandler; +import io.netty.util.Timeout; +import io.netty.util.Timer; +import io.netty.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.forward.PositionData; +import org.traccar.forward.PositionForwarder; +import org.traccar.forward.ResultHandler; +import org.traccar.model.Device; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +@Singleton +@ChannelHandler.Sharable +public class PositionForwardingHandler extends BaseDataHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(PositionForwardingHandler.class); + + private final CacheManager cacheManager; + private final Timer timer; + + private final PositionForwarder positionForwarder; + + private final boolean retryEnabled; + private final int retryDelay; + private final int retryCount; + private final int retryLimit; + + private final AtomicInteger deliveryPending; + + @Inject + public PositionForwardingHandler( + Config config, CacheManager cacheManager, Timer timer, @Nullable PositionForwarder positionForwarder) { + + this.cacheManager = cacheManager; + this.timer = timer; + this.positionForwarder = positionForwarder; + + this.retryEnabled = config.getBoolean(Keys.FORWARD_RETRY_ENABLE); + this.retryDelay = config.getInteger(Keys.FORWARD_RETRY_DELAY); + this.retryCount = config.getInteger(Keys.FORWARD_RETRY_COUNT); + this.retryLimit = config.getInteger(Keys.FORWARD_RETRY_LIMIT); + + this.deliveryPending = new AtomicInteger(); + } + + class AsyncRequestAndCallback implements ResultHandler, TimerTask { + + private final PositionData positionData; + + private int retries = 0; + + AsyncRequestAndCallback(PositionData positionData) { + this.positionData = positionData; + deliveryPending.incrementAndGet(); + } + + private void send() { + positionForwarder.forward(positionData, this); + } + + private void retry(Throwable throwable) { + boolean scheduled = false; + try { + if (retryEnabled && deliveryPending.get() <= retryLimit && retries < retryCount) { + schedule(); + scheduled = true; + } + } finally { + int pending = scheduled ? deliveryPending.get() : deliveryPending.decrementAndGet(); + LOGGER.warn("Position forwarding failed: " + pending + " pending", throwable); + } + } + + private void schedule() { + timer.newTimeout(this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); + } + + @Override + public void onResult(boolean success, Throwable throwable) { + if (success) { + deliveryPending.decrementAndGet(); + } else { + retry(throwable); + } + } + + @Override + public void run(Timeout timeout) { + boolean sent = false; + try { + if (!timeout.isCancelled()) { + send(); + sent = true; + } + } finally { + if (!sent) { + deliveryPending.decrementAndGet(); + } + } + } + } + + @Override + protected Position handlePosition(Position position) { + if (positionForwarder != null) { + PositionData positionData = new PositionData(); + positionData.setPosition(position); + positionData.setDevice(cacheManager.getObject(Device.class, position.getDeviceId())); + new AsyncRequestAndCallback(positionData).send(); + } + return position; + } + +} diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java deleted file mode 100644 index 2d2e3dc8f..000000000 --- a/src/main/java/org/traccar/WebDataHandler.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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. - * 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; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.netty.channel.ChannelHandler; -import io.netty.util.Timer; -import io.netty.util.Timeout; -import io.netty.util.TimerTask; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.helper.Checksum; -import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.model.Group; -import org.traccar.session.cache.CacheManager; - -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.InvocationCallback; -import java.util.HashMap; -import java.util.Map; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.Calendar; -import java.util.Formatter; -import java.util.Locale; -import java.util.TimeZone; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -@Singleton -@ChannelHandler.Sharable -public class WebDataHandler extends BaseDataHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(WebDataHandler.class); - - private static final String KEY_POSITION = "position"; - private static final String KEY_DEVICE = "device"; - - private final CacheManager cacheManager; - private final ObjectMapper objectMapper; - private final Client client; - private final Timer timer; - - private final String url; - private final String header; - private final boolean json; - private final boolean urlVariables; - - private final boolean retryEnabled; - private final int retryDelay; - private final int retryCount; - private final int retryLimit; - - private final AtomicInteger deliveryPending; - - @Inject - public WebDataHandler( - Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client, Timer timer) { - - this.cacheManager = cacheManager; - this.objectMapper = objectMapper; - this.client = client; - this.timer = timer; - this.url = config.getString(Keys.FORWARD_URL); - this.header = config.getString(Keys.FORWARD_HEADER); - this.json = config.getBoolean(Keys.FORWARD_JSON); - this.urlVariables = config.getBoolean(Keys.FORWARD_URL_VARIABLES); - - this.retryEnabled = config.getBoolean(Keys.FORWARD_RETRY_ENABLE); - this.retryDelay = config.getInteger(Keys.FORWARD_RETRY_DELAY, 100); - this.retryCount = config.getInteger(Keys.FORWARD_RETRY_COUNT, 10); - this.retryLimit = config.getInteger(Keys.FORWARD_RETRY_LIMIT, 100); - - this.deliveryPending = new AtomicInteger(0); - } - - private static String formatSentence(Position position) { - - StringBuilder s = new StringBuilder("$GPRMC,"); - - try (Formatter f = new Formatter(s, Locale.ENGLISH)) { - - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); - calendar.setTimeInMillis(position.getFixTime().getTime()); - - f.format("%1$tH%1$tM%1$tS.%1$tL,A,", calendar); - - double lat = position.getLatitude(); - double lon = position.getLongitude(); - - f.format("%02d%07.4f,%c,", (int) Math.abs(lat), Math.abs(lat) % 1 * 60, lat < 0 ? 'S' : 'N'); - f.format("%03d%07.4f,%c,", (int) Math.abs(lon), Math.abs(lon) % 1 * 60, lon < 0 ? 'W' : 'E'); - - f.format("%.2f,%.2f,", position.getSpeed(), position.getCourse()); - f.format("%1$td%1$tm%1$ty,,", calendar); - } - - s.append(Checksum.nmea(s.substring(1))); - - return s.toString(); - } - - // OpenGTS status code - private String calculateStatus(Position position) { - if (position.hasAttribute(Position.KEY_ALARM)) { - return "0xF841"; // STATUS_PANIC_ON - } else if (position.getSpeed() < 1.0) { - return "0xF020"; // STATUS_LOCATION - } else { - return "0xF11C"; // STATUS_MOTION_MOVING - } - } - - public String formatRequest(Position position) throws UnsupportedEncodingException, JsonProcessingException { - - Device device = cacheManager.getObject(Device.class, position.getDeviceId()); - - String request = url - .replace("{name}", URLEncoder.encode(device.getName(), StandardCharsets.UTF_8.name())) - .replace("{uniqueId}", device.getUniqueId()) - .replace("{status}", device.getStatus()) - .replace("{deviceId}", String.valueOf(position.getDeviceId())) - .replace("{protocol}", String.valueOf(position.getProtocol())) - .replace("{deviceTime}", String.valueOf(position.getDeviceTime().getTime())) - .replace("{fixTime}", String.valueOf(position.getFixTime().getTime())) - .replace("{valid}", String.valueOf(position.getValid())) - .replace("{latitude}", String.valueOf(position.getLatitude())) - .replace("{longitude}", String.valueOf(position.getLongitude())) - .replace("{altitude}", String.valueOf(position.getAltitude())) - .replace("{speed}", String.valueOf(position.getSpeed())) - .replace("{course}", String.valueOf(position.getCourse())) - .replace("{accuracy}", String.valueOf(position.getAccuracy())) - .replace("{statusCode}", calculateStatus(position)); - - if (position.getAddress() != null) { - request = request.replace( - "{address}", URLEncoder.encode(position.getAddress(), StandardCharsets.UTF_8.name())); - } - - if (request.contains("{attributes}")) { - String attributes = objectMapper.writeValueAsString(position.getAttributes()); - request = request.replace( - "{attributes}", URLEncoder.encode(attributes, StandardCharsets.UTF_8.name())); - } - - if (request.contains("{gprmc}")) { - request = request.replace("{gprmc}", formatSentence(position)); - } - - if (request.contains("{group}")) { - String deviceGroupName = ""; - if (device.getGroupId() != 0) { - Group group = cacheManager.getObject(Group.class, device.getGroupId()); - if (group != null) { - deviceGroupName = group.getName(); - } - } - - request = request.replace("{group}", URLEncoder.encode(deviceGroupName, StandardCharsets.UTF_8.name())); - } - - return request; - } - - class AsyncRequestAndCallback implements InvocationCallback, TimerTask { - - private int retries = 0; - private Map payload; - private final Invocation.Builder requestBuilder; - private MediaType mediaType = MediaType.APPLICATION_JSON_TYPE; - - AsyncRequestAndCallback(Position position) { - - String formattedUrl; - try { - formattedUrl = json && !urlVariables ? url : formatRequest(position); - } catch (UnsupportedEncodingException | JsonProcessingException e) { - throw new RuntimeException("Forwarding formatting error", e); - } - - requestBuilder = client.target(formattedUrl).request(); - if (header != null && !header.isEmpty()) { - for (String line: header.split("\\r?\\n")) { - String[] values = line.split(":", 2); - String headerName = values[0].trim(); - String headerValue = values[1].trim(); - if (headerName.equals(HttpHeaders.CONTENT_TYPE)) { - mediaType = MediaType.valueOf(headerValue); - } else { - requestBuilder.header(headerName, headerValue); - } - } - } - - if (json) { - payload = prepareJsonPayload(position); - } - - deliveryPending.incrementAndGet(); - } - - private void send() { - LOGGER.debug("Position forwarding initiated"); - if (json) { - try { - Entity entity = Entity.entity(objectMapper.writeValueAsString(payload), mediaType); - requestBuilder.async().post(entity, this); - } catch (JsonProcessingException e) { - throw new RuntimeException("Failed to serialize location to json", e); - } - } else { - requestBuilder.async().get(this); - } - } - - private void retry(Throwable throwable) { - boolean scheduled = false; - try { - if (retryEnabled && deliveryPending.get() <= retryLimit && retries < retryCount) { - schedule(); - scheduled = true; - } - } finally { - int pending = scheduled ? deliveryPending.get() : deliveryPending.decrementAndGet(); - LOGGER.warn("Position forwarding failed: " + pending + " pending", throwable); - } - } - - private void schedule() { - timer.newTimeout(this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); - } - - @Override - public void completed(Response response) { - if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { - deliveryPending.decrementAndGet(); - LOGGER.debug("Position forwarding succeeded"); - } else { - retry(new RuntimeException("Status code 2xx expected")); - } - } - - @Override - public void failed(Throwable throwable) { - retry(throwable); - } - - @Override - public void run(Timeout timeout) { - boolean sent = false; - try { - if (!timeout.isCancelled()) { - send(); - sent = true; - } - } finally { - if (!sent) { - deliveryPending.decrementAndGet(); - } - } - } - - } - - @Override - protected Position handlePosition(Position position) { - - if (url != null) { - AsyncRequestAndCallback request = new AsyncRequestAndCallback(position); - request.send(); - } - - return position; - } - - private Map prepareJsonPayload(Position position) { - - Map data = new HashMap<>(); - Device device = cacheManager.getObject(Device.class, position.getDeviceId()); - - data.put(KEY_POSITION, position); - - if (device != null) { - data.put(KEY_DEVICE, device); - } - - return data; - } - -} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 1da01518c..b60cd82a0 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -720,14 +720,6 @@ public final class Keys { "forward.json", List.of(KeyType.CONFIG)); - /** - * Boolean value to enable URL parameters in json mode. For example, {uniqueId} for device identifier, - * {latitude} and {longitude} for coordinates. - */ - public static final ConfigKey FORWARD_URL_VARIABLES = new BooleanConfigKey( - "forward.urlVariables", - List.of(KeyType.CONFIG)); - /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial * delivery fails, because of an unreachable server or an HTTP response different from '2xx', the software waits @@ -745,7 +737,8 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_DELAY = new IntegerConfigKey( "forward.retry.delay", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), + 100); /** * Position forwarding retry maximum retries. @@ -753,7 +746,8 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_COUNT = new IntegerConfigKey( "forward.retry.count", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), + 10); /** * Position forwarding retry pending positions limit. @@ -761,7 +755,8 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_LIMIT = new IntegerConfigKey( "forward.retry.limit", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), + 100); /** * Events forwarding URL. diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 7c82454b2..1eec7e097 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -129,7 +129,11 @@ public class NotificationManager { if (event.getMaintenanceId() != 0) { eventData.setMaintenance(cacheManager.getObject(Maintenance.class, event.getMaintenanceId())); } - eventForwarder.forward(eventData); + eventForwarder.forward(eventData, (success, throwable) -> { + if (!success) { + LOGGER.warn("Event forwarding failed", throwable); + } + }); } } diff --git a/src/main/java/org/traccar/forward/EventForwarder.java b/src/main/java/org/traccar/forward/EventForwarder.java index c3ad5efc0..1f991c0b5 100644 --- a/src/main/java/org/traccar/forward/EventForwarder.java +++ b/src/main/java/org/traccar/forward/EventForwarder.java @@ -16,5 +16,5 @@ package org.traccar.forward; public interface EventForwarder { - void forward(EventData eventData); + void forward(EventData eventData, ResultHandler resultHandler); } diff --git a/src/main/java/org/traccar/forward/EventForwarderJson.java b/src/main/java/org/traccar/forward/EventForwarderJson.java index c136fd4e2..7527d568a 100644 --- a/src/main/java/org/traccar/forward/EventForwarderJson.java +++ b/src/main/java/org/traccar/forward/EventForwarderJson.java @@ -15,33 +15,29 @@ */ package org.traccar.forward; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.core.Response; public class EventForwarderJson implements EventForwarder { - private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarderJson.class); - private final String url; private final String header; private final Client client; - @Inject public EventForwarderJson(Config config, Client client) { this.client = client; url = config.getString(Keys.EVENT_FORWARD_URL); header = config.getString(Keys.EVENT_FORWARD_HEADERS); } - public void forward(EventData eventData) { + @Override + public void forward(EventData eventData, ResultHandler resultHandler) { var requestBuilder = client.target(url).request(); if (header != null && !header.isEmpty()) { @@ -51,14 +47,20 @@ public class EventForwarderJson implements EventForwarder { } } - requestBuilder.async().post(Entity.json(eventData), new InvocationCallback<>() { + requestBuilder.async().post(Entity.json(eventData), new InvocationCallback() { @Override - public void completed(Object o) { + public void completed(Response response) { + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { + resultHandler.onResult(true, null); + } else { + int code = response.getStatusInfo().getStatusCode(); + resultHandler.onResult(false, new RuntimeException("HTTP code " + code)); + } } @Override public void failed(Throwable throwable) { - LOGGER.warn("Event forwarding failed", throwable); + resultHandler.onResult(false, throwable); } }); } diff --git a/src/main/java/org/traccar/forward/PositionData.java b/src/main/java/org/traccar/forward/PositionData.java new file mode 100644 index 000000000..784cf52f5 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionData.java @@ -0,0 +1,45 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.annotation.JsonInclude; +import org.traccar.model.Device; +import org.traccar.model.Position; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PositionData { + + private Position position; + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + + private Device device; + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } + +} diff --git a/src/main/java/org/traccar/forward/PositionForwarder.java b/src/main/java/org/traccar/forward/PositionForwarder.java new file mode 100644 index 000000000..58bd1dcc7 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarder.java @@ -0,0 +1,20 @@ +/* + * 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.forward; + +public interface PositionForwarder { + void forward(PositionData positionData, ResultHandler resultHandler); +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderJson.java b/src/main/java/org/traccar/forward/PositionForwarderJson.java new file mode 100644 index 000000000..27b96308e --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderJson.java @@ -0,0 +1,86 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class PositionForwarderJson implements PositionForwarder { + + private final String url; + private final String header; + + private final Client client; + private final ObjectMapper objectMapper; + + public PositionForwarderJson(Config config, Client client, ObjectMapper objectMapper) { + this.client = client; + this.objectMapper = objectMapper; + this.url = config.getString(Keys.FORWARD_URL); + this.header = config.getString(Keys.FORWARD_HEADER); + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + var requestBuilder = client.target(url).request(); + + MediaType mediaType = MediaType.APPLICATION_JSON_TYPE; + if (header != null && !header.isEmpty()) { + for (String line: header.split("\\r?\\n")) { + String[] values = line.split(":", 2); + String headerName = values[0].trim(); + String headerValue = values[1].trim(); + if (headerName.equals(HttpHeaders.CONTENT_TYPE)) { + mediaType = MediaType.valueOf(headerValue); + } else { + requestBuilder.header(headerName, headerValue); + } + } + } + + try { + var entity = Entity.entity(objectMapper.writeValueAsString(positionData), mediaType); + requestBuilder.async().post(entity, new InvocationCallback() { + @Override + public void completed(Response response) { + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { + resultHandler.onResult(true, null); + } else { + int code = response.getStatusInfo().getStatusCode(); + resultHandler.onResult(false, new RuntimeException("HTTP code " + code)); + } + } + + @Override + public void failed(Throwable throwable) { + resultHandler.onResult(false, throwable); + } + }); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderUrl.java b/src/main/java/org/traccar/forward/PositionForwarderUrl.java new file mode 100644 index 000000000..53cc7ad24 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderUrl.java @@ -0,0 +1,166 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.helper.Checksum; +import org.traccar.model.Device; +import org.traccar.model.Position; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.core.Response; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Calendar; +import java.util.Formatter; +import java.util.Locale; +import java.util.TimeZone; + +public class PositionForwarderUrl implements PositionForwarder { + + private final String url; + private final String header; + + private final Client client; + private final ObjectMapper objectMapper; + + public PositionForwarderUrl(Config config, Client client, ObjectMapper objectMapper) { + this.client = client; + this.objectMapper = objectMapper; + this.url = config.getString(Keys.FORWARD_URL); + this.header = config.getString(Keys.FORWARD_HEADER); + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + try { + String url = formatRequest(positionData); + var requestBuilder = client.target(url).request(); + + if (header != null && !header.isEmpty()) { + for (String line: header.split("\\r?\\n")) { + String[] values = line.split(":", 2); + String headerName = values[0].trim(); + String headerValue = values[1].trim(); + requestBuilder.header(headerName, headerValue); + } + } + + requestBuilder.async().get(new InvocationCallback() { + @Override + public void completed(Response response) { + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { + resultHandler.onResult(true, null); + } else { + int code = response.getStatusInfo().getStatusCode(); + resultHandler.onResult(false, new RuntimeException("HTTP code " + code)); + } + } + + @Override + public void failed(Throwable throwable) { + resultHandler.onResult(false, throwable); + } + }); + } catch (UnsupportedEncodingException | JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + + public String formatRequest( + PositionData positionData) throws UnsupportedEncodingException, JsonProcessingException { + + Position position = positionData.getPosition(); + Device device = positionData.getDevice(); + + String request = url + .replace("{name}", URLEncoder.encode(device.getName(), StandardCharsets.UTF_8)) + .replace("{uniqueId}", device.getUniqueId()) + .replace("{status}", device.getStatus()) + .replace("{deviceId}", String.valueOf(position.getDeviceId())) + .replace("{protocol}", String.valueOf(position.getProtocol())) + .replace("{deviceTime}", String.valueOf(position.getDeviceTime().getTime())) + .replace("{fixTime}", String.valueOf(position.getFixTime().getTime())) + .replace("{valid}", String.valueOf(position.getValid())) + .replace("{latitude}", String.valueOf(position.getLatitude())) + .replace("{longitude}", String.valueOf(position.getLongitude())) + .replace("{altitude}", String.valueOf(position.getAltitude())) + .replace("{speed}", String.valueOf(position.getSpeed())) + .replace("{course}", String.valueOf(position.getCourse())) + .replace("{accuracy}", String.valueOf(position.getAccuracy())) + .replace("{statusCode}", calculateStatus(position)); + + if (position.getAddress() != null) { + request = request.replace( + "{address}", URLEncoder.encode(position.getAddress(), StandardCharsets.UTF_8)); + } + + if (request.contains("{attributes}")) { + String attributes = objectMapper.writeValueAsString(position.getAttributes()); + request = request.replace( + "{attributes}", URLEncoder.encode(attributes, StandardCharsets.UTF_8)); + } + + if (request.contains("{gprmc}")) { + request = request.replace("{gprmc}", formatSentence(position)); + } + + return request; + } + + private static String formatSentence(Position position) { + + StringBuilder s = new StringBuilder("$GPRMC,"); + + try (Formatter f = new Formatter(s, Locale.ENGLISH)) { + + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); + calendar.setTimeInMillis(position.getFixTime().getTime()); + + f.format("%1$tH%1$tM%1$tS.%1$tL,A,", calendar); + + double lat = position.getLatitude(); + double lon = position.getLongitude(); + + f.format("%02d%07.4f,%c,", (int) Math.abs(lat), Math.abs(lat) % 1 * 60, lat < 0 ? 'S' : 'N'); + f.format("%03d%07.4f,%c,", (int) Math.abs(lon), Math.abs(lon) % 1 * 60, lon < 0 ? 'W' : 'E'); + + f.format("%.2f,%.2f,", position.getSpeed(), position.getCourse()); + f.format("%1$td%1$tm%1$ty,,", calendar); + } + + s.append(Checksum.nmea(s.substring(1))); + + return s.toString(); + } + + // OpenGTS status code + private String calculateStatus(Position position) { + if (position.hasAttribute(Position.KEY_ALARM)) { + return "0xF841"; // STATUS_PANIC_ON + } else if (position.getSpeed() < 1.0) { + return "0xF020"; // STATUS_LOCATION + } else { + return "0xF11C"; // STATUS_MOTION_MOVING + } + } + +} diff --git a/src/main/java/org/traccar/forward/ResultHandler.java b/src/main/java/org/traccar/forward/ResultHandler.java new file mode 100644 index 000000000..009daf495 --- /dev/null +++ b/src/main/java/org/traccar/forward/ResultHandler.java @@ -0,0 +1,20 @@ +/* + * 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.forward; + +public interface ResultHandler { + void onResult(boolean success, Throwable throwable); +} diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java deleted file mode 100644 index 99dbb83fa..000000000 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.traccar; - -import org.junit.Test; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.session.cache.CacheManager; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class WebDataHandlerTest extends ProtocolTest { - - @Test - public void testFormatRequest() throws Exception { - - Config config = new Config(); - config.setString(Keys.FORWARD_URL, "http://localhost/?fixTime={fixTime}&gprmc={gprmc}&name={name}"); - - Position position = position("2016-01-01 01:02:03.000", true, 20, 30); - - var device = mock(Device.class); - when(device.getId()).thenReturn(1L); - when(device.getName()).thenReturn("test"); - when(device.getUniqueId()).thenReturn("123456789012345"); - when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); - var cacheManager = mock(CacheManager.class); - when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); - - WebDataHandler handler = new WebDataHandler(config, cacheManager, null, null, null); - - assertEquals( - "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", - handler.formatRequest(position)); - - } - -} diff --git a/src/test/java/org/traccar/forward/PositionForwarderUrlTest.java b/src/test/java/org/traccar/forward/PositionForwarderUrlTest.java new file mode 100644 index 000000000..522958052 --- /dev/null +++ b/src/test/java/org/traccar/forward/PositionForwarderUrlTest.java @@ -0,0 +1,42 @@ +package org.traccar.forward; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Device; +import org.traccar.model.Position; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class PositionForwarderUrlTest extends ProtocolTest { + + @Test + public void testFormatRequest() throws Exception { + + Config config = new Config(); + config.setString(Keys.FORWARD_URL, "http://localhost/?fixTime={fixTime}&gprmc={gprmc}&name={name}"); + + Position position = position("2016-01-01 01:02:03.000", true, 20, 30); + + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + when(device.getName()).thenReturn("test"); + when(device.getUniqueId()).thenReturn("123456789012345"); + when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); + + PositionData positionData = new PositionData(); + positionData.setPosition(position); + positionData.setDevice(device); + + PositionForwarderUrl forwarder = new PositionForwarderUrl(config, null, null); + + assertEquals( + "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", + forwarder.formatRequest(positionData)); + + } + +} -- cgit v1.2.3 From 826c661819d044c8f1cf950795ee0f33cc7675c6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 16:44:15 -0800 Subject: Implement Kafka forwarding --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 21 +++++--- src/main/java/org/traccar/config/Keys.java | 23 +++++--- .../org/traccar/forward/EventForwarderKafka.java | 61 ++++++++++++++++++++++ .../traccar/forward/PositionForwarderKafka.java | 55 +++++++++++++++++++ 5 files changed, 148 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/traccar/forward/EventForwarderKafka.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarderKafka.java (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 0e7d77bce..a5daf5924 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "com.sun.xml.bind:jaxb-impl:3.0.2" // needs upgrade implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.314" + implementation "org.apache.kafka:kafka-clients:3.3.1" implementation ("com.google.firebase:firebase-admin:9.0.0") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 9d450fef7..6e59527bc 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -37,8 +37,10 @@ import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; +import org.traccar.forward.EventForwarderKafka; 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; @@ -314,9 +316,13 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static EventForwarder provideEventForwarder(Config config, Client client) { + public static EventForwarder provideEventForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarderJson(config, client); + if (config.getString(Keys.EVENT_FORWARD_TYPE).equals("kafka")) { + return new EventForwarderKafka(config, objectMapper); + } else { + return new EventForwarderJson(config, client); + } } return null; } @@ -325,10 +331,13 @@ public class MainModule extends AbstractModule { @Provides public static PositionForwarder providePositionForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.FORWARD_URL)) { - if (config.getBoolean(Keys.FORWARD_JSON)) { - return new PositionForwarderJson(config, client, objectMapper); - } else { - return new PositionForwarderUrl(config, client, objectMapper); + switch (config.getString(Keys.FORWARD_TYPE)) { + case "json": + return new PositionForwarderJson(config, client, objectMapper); + case "kafka": + return new PositionForwarderKafka(config, objectMapper); + default: + return new PositionForwarderUrl(config, client, objectMapper); } } return null; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index b60cd82a0..2224192d9 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -698,6 +698,14 @@ public final class Keys { List.of(KeyType.CONFIG), "max-age=3600,public"); + /** + * Position forwarding format. Available options are "url", "json" and "kafka". Default is "url". + */ + public static final ConfigKey FORWARD_TYPE = new StringConfigKey( + "forward.type", + List.of(KeyType.CONFIG), + "url"); + /** * URL to forward positions. Data is passed through URL parameters. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. @@ -713,13 +721,6 @@ public final class Keys { "forward.header", List.of(KeyType.CONFIG)); - /** - * Boolean value to enable forwarding in JSON format. - */ - public static final ConfigKey FORWARD_JSON = new BooleanConfigKey( - "forward.json", - List.of(KeyType.CONFIG)); - /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial * delivery fails, because of an unreachable server or an HTTP response different from '2xx', the software waits @@ -758,6 +759,14 @@ public final class Keys { List.of(KeyType.CONFIG), 100); + /** + * Events forwarding format. Available options are "json" and "kafka". Default is "json". + */ + public static final ConfigKey EVENT_FORWARD_TYPE = new StringConfigKey( + "event.forward.type", + List.of(KeyType.CONFIG), + "json"); + /** * Events forwarding URL. */ diff --git a/src/main/java/org/traccar/forward/EventForwarderKafka.java b/src/main/java/org/traccar/forward/EventForwarderKafka.java new file mode 100644 index 000000000..71e06ddd1 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarderKafka.java @@ -0,0 +1,61 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.util.Properties; + +public class EventForwarderKafka implements EventForwarder { + + private final Producer producer; + private final ObjectMapper objectMapper; + + public EventForwarderKafka(Config config, ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + Properties properties = new Properties(); + properties.put("bootstrap.servers", config.getString(Keys.EVENT_FORWARD_URL)); + properties.put("acks", "all"); + properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + producer = new KafkaProducer<>(properties); + } + + @SuppressWarnings("deprecation") + @Override + protected void finalize() { + producer.close(); + } + + @Override + public void forward(EventData eventData, ResultHandler resultHandler) { + try { + String key = Long.toString(eventData.getDevice().getId()); + String value = objectMapper.writeValueAsString(eventData); + producer.send(new ProducerRecord<>("events", key, value)); + resultHandler.onResult(true, null); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderKafka.java b/src/main/java/org/traccar/forward/PositionForwarderKafka.java new file mode 100644 index 000000000..3921539ac --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderKafka.java @@ -0,0 +1,55 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.util.Properties; + +public class PositionForwarderKafka implements PositionForwarder { + + private final Producer producer; + private final ObjectMapper objectMapper; + + public PositionForwarderKafka(Config config, ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + Properties properties = new Properties(); + properties.put("bootstrap.servers", config.getString(Keys.EVENT_FORWARD_URL)); + properties.put("acks", "all"); + properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + producer = new KafkaProducer<>(properties); + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + try { + String key = Long.toString(positionData.getDevice().getId()); + String value = objectMapper.writeValueAsString(positionData); + producer.send(new ProducerRecord<>("positions", key, value)); + resultHandler.onResult(true, null); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + +} -- cgit v1.2.3 From 77c1e617587947c431b77773f53da5e222f4dd61 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 14 Nov 2022 08:19:22 -0800 Subject: Customizable Kafka topic --- src/main/java/org/traccar/config/Keys.java | 16 ++++++++++++++++ .../java/org/traccar/forward/EventForwarderKafka.java | 5 ++++- .../java/org/traccar/forward/PositionForwarderKafka.java | 7 +++++-- 3 files changed, 25 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 2224192d9..9ae71921e 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -706,6 +706,14 @@ public final class Keys { List.of(KeyType.CONFIG), "url"); + /** + * Position forwarding Kafka topic. + */ + public static final ConfigKey FORWARD_TOPIC = new StringConfigKey( + "forward.topic", + List.of(KeyType.CONFIG), + "positions"); + /** * URL to forward positions. Data is passed through URL parameters. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. @@ -767,6 +775,14 @@ public final class Keys { List.of(KeyType.CONFIG), "json"); + /** + * Events forwarding Kafka topic. + */ + public static final ConfigKey EVENT_FORWARD_TOPIC = new StringConfigKey( + "event.forward.topic", + List.of(KeyType.CONFIG), + "events"); + /** * Events forwarding URL. */ diff --git a/src/main/java/org/traccar/forward/EventForwarderKafka.java b/src/main/java/org/traccar/forward/EventForwarderKafka.java index 71e06ddd1..db97d22de 100644 --- a/src/main/java/org/traccar/forward/EventForwarderKafka.java +++ b/src/main/java/org/traccar/forward/EventForwarderKafka.java @@ -30,6 +30,8 @@ public class EventForwarderKafka implements EventForwarder { private final Producer producer; private final ObjectMapper objectMapper; + private final String topic; + public EventForwarderKafka(Config config, ObjectMapper objectMapper) { this.objectMapper = objectMapper; Properties properties = new Properties(); @@ -38,6 +40,7 @@ public class EventForwarderKafka implements EventForwarder { properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); producer = new KafkaProducer<>(properties); + topic = config.getString(Keys.EVENT_FORWARD_TOPIC); } @SuppressWarnings("deprecation") @@ -51,7 +54,7 @@ public class EventForwarderKafka implements EventForwarder { try { String key = Long.toString(eventData.getDevice().getId()); String value = objectMapper.writeValueAsString(eventData); - producer.send(new ProducerRecord<>("events", key, value)); + producer.send(new ProducerRecord<>(topic, key, value)); resultHandler.onResult(true, null); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); diff --git a/src/main/java/org/traccar/forward/PositionForwarderKafka.java b/src/main/java/org/traccar/forward/PositionForwarderKafka.java index 3921539ac..7432e9364 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderKafka.java +++ b/src/main/java/org/traccar/forward/PositionForwarderKafka.java @@ -30,14 +30,17 @@ public class PositionForwarderKafka implements PositionForwarder { private final Producer producer; private final ObjectMapper objectMapper; + private final String topic; + public PositionForwarderKafka(Config config, ObjectMapper objectMapper) { this.objectMapper = objectMapper; Properties properties = new Properties(); - properties.put("bootstrap.servers", config.getString(Keys.EVENT_FORWARD_URL)); + properties.put("bootstrap.servers", config.getString(Keys.FORWARD_URL)); properties.put("acks", "all"); properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); producer = new KafkaProducer<>(properties); + topic = config.getString(Keys.FORWARD_TOPIC); } @Override @@ -45,7 +48,7 @@ public class PositionForwarderKafka implements PositionForwarder { try { String key = Long.toString(positionData.getDevice().getId()); String value = objectMapper.writeValueAsString(positionData); - producer.send(new ProducerRecord<>("positions", key, value)); + producer.send(new ProducerRecord<>(topic, key, value)); resultHandler.onResult(true, null); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); -- cgit v1.2.3 From 4c973263a82d7c3515a8054a24e3396dfcab0e93 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 16 Nov 2022 06:54:30 -0800 Subject: Fix missing device --- src/main/java/org/traccar/database/NotificationManager.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 1eec7e097..cb971b082 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -24,6 +24,7 @@ import org.traccar.forward.EventData; import org.traccar.forward.EventForwarder; import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; +import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; @@ -123,6 +124,7 @@ public class NotificationManager { EventData eventData = new EventData(); eventData.setEvent(event); eventData.setPosition(position); + eventData.setDevice(cacheManager.getObject(Device.class, event.getDeviceId())); if (event.getGeofenceId() != 0) { eventData.setGeofence(cacheManager.getObject(Geofence.class, event.getGeofenceId())); } -- cgit v1.2.3 From 63cab28f909343476ffa39983da533e169f02838 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 22 Nov 2022 07:30:09 -0800 Subject: Fix steps decoding --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index f0ae28756..eb5e16de2 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -266,8 +266,8 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { hasLocation = true; break; case 0x30: - buf.readUnsignedInt(); // timestamp - position.set(Position.KEY_STEPS, buf.readUnsignedInt()); + buf.readUnsignedIntLE(); // timestamp + position.set(Position.KEY_STEPS, buf.readUnsignedIntLE()); break; case 0x31: int i = 1; -- cgit v1.2.3 From 19d10da19db57b2119c295cb452a271c3de48f85 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 24 Nov 2022 11:06:04 -0800 Subject: ATrack AK11 text responses --- .../org/traccar/protocol/AtrackProtocolDecoder.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 4567582db..340641729 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -100,7 +100,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { this.form = form; } - private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { if (channel != null) { ByteBuf response = Unpooled.buffer(12); response.writeShort(0xfe02); @@ -526,20 +526,24 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private List decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - int startIndex = -1; - for (int i = 0; i < 4; i++) { - startIndex = sentence.indexOf(',', startIndex + 1); + int positionIndex = -1; + for (int i = 0; i < 5; i++) { + positionIndex = sentence.indexOf(',', positionIndex + 1); } - int endIndex = sentence.indexOf(',', startIndex + 1); - String imei = sentence.substring(startIndex + 1, endIndex); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + String[] headers = sentence.substring(0, positionIndex).split(","); + long id = Long.parseLong(headers[2]); + int index = Integer.parseInt(headers[3]); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, headers[4]); if (deviceSession == null) { return null; } + sendResponse(channel, remoteAddress, id, index); + List positions = new LinkedList<>(); - String[] lines = sentence.substring(endIndex + 1).split("\r\n"); + String[] lines = sentence.substring(positionIndex + 1).split("\r\n"); for (String line : lines) { Position position = decodeTextLine(deviceSession, line); -- cgit v1.2.3 From 146de22b51139edcc3132f403e86006ac1fc3419 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 10:31:12 -0800 Subject: Support GL600 GPS lock --- src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 9fa550ded..9ed44f565 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -143,7 +143,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { boolean responseRequired = false; - while (buf.readableBytes() > 1) { + while (buf.readableBytes() >= 17) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 98c587a81..fc52e32e3 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Jt600ProtocolDecoder(null)); + verifyPositions(decoder, binary( + "2480433966040111002718031919195822424550114158888E15A40000F124080000000000F00F110A24991900000DF0C7")); + verifyPosition(decoder, buffer( "(8000632862,P45,290322,132412,25.28217,S,57.54683,W,A,0,0,5,0,0000000000,0,0,9,0)")); -- cgit v1.2.3 From 20ca33bf17c30bf2335d85365a224bc437e0347b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 11:14:15 -0800 Subject: Unknown device throttling --- src/main/java/org/traccar/config/Keys.java | 9 ++++- .../org/traccar/database/DeviceLookupService.java | 47 ++++++++++++++-------- 2 files changed, 38 insertions(+), 18 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 9ae71921e..09662fc85 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -452,7 +452,14 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * By default server syncs with the database if it encounters and unknown device. This flag allows to disable that + * Throttle unknown device database queries when it sends repeated requests. + */ + public static final ConfigKey DATABASE_THROTTLE_UNKNOWN = new BooleanConfigKey( + "database.throttleUnknown", + List.of(KeyType.CONFIG)); + + /** + * By default, server syncs with the database if it encounters and unknown device. This flag allows to disable that * behavior to improve performance in some cases. */ public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new BooleanConfigKey( diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index 28910c24a..583b2ae35 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -20,6 +20,8 @@ import io.netty.util.Timer; import io.netty.util.TimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -45,6 +47,8 @@ public class DeviceLookupService { private final Storage storage; private final Timer timer; + private final boolean throttlingEnabled; + private static class IdentifierInfo { private long lastQuery; private long delay; @@ -70,36 +74,45 @@ public class DeviceLookupService { private final Map identifierMap = new ConcurrentHashMap<>(); @Inject - public DeviceLookupService(Storage storage, Timer timer) { + public DeviceLookupService(Config config, Storage storage, Timer timer) { this.storage = storage; this.timer = timer; + throttlingEnabled = config.getBoolean(Keys.DATABASE_THROTTLE_UNKNOWN); } private synchronized boolean isThrottled(String uniqueId) { - IdentifierInfo info = identifierMap.get(uniqueId); - return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.get(uniqueId); + return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + } else { + return false; + } } private synchronized void lookupSucceeded(String uniqueId) { - IdentifierInfo info = identifierMap.remove(uniqueId); - if (info != null) { - info.timeout.cancel(); + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.remove(uniqueId); + if (info != null) { + info.timeout.cancel(); + } } } private synchronized void lookupFailed(String uniqueId) { - IdentifierInfo info = identifierMap.get(uniqueId); - if (info != null) { - info.timeout.cancel(); - info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); - } else { - info = new IdentifierInfo(); - identifierMap.put(uniqueId, info); - info.delay = THROTTLE_MIN_MS; + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.get(uniqueId); + if (info != null) { + info.timeout.cancel(); + info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); + } else { + info = new IdentifierInfo(); + identifierMap.put(uniqueId, info); + info.delay = THROTTLE_MIN_MS; + } + info.lastQuery = System.currentTimeMillis(); + info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); + LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } - info.lastQuery = System.currentTimeMillis(); - info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); - LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } public Device lookup(String[] uniqueIds) { -- cgit v1.2.3 From 82cd47bf236808d4ef13b5c654ed5b52ed2746bb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 15:32:12 -0800 Subject: Update java versions --- build.gradle | 24 +++++++++++----------- .../java/org/traccar/storage/DatabaseModule.java | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index a5daf5924..3dcef5a8d 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ ext { jettyVersion = "10.0.12" // jetty 11 javax to jakarta jerseyVersion = "2.37" // jersey 3 javax to jakarta jacksonVersion = "2.13.4" // same version as jersey-media-json-jackson dependency - protobufVersion = "3.21.7" + protobufVersion = "3.21.9" } sourceCompatibility = "11" @@ -42,16 +42,16 @@ enforce { dependencies { implementation "commons-codec:commons-codec:1.15" implementation "com.h2database:h2:2.1.214" - implementation "mysql:mysql-connector-java:8.0.30" - implementation "org.postgresql:postgresql:42.5.0" + implementation "com.mysql:mysql-connector-j:8.0.31" + implementation "org.postgresql:postgresql:42.5.1" implementation "com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre11" implementation "com.zaxxer:HikariCP:5.0.1" - implementation "io.netty:netty-all:4.1.82.Final" - implementation "org.slf4j:slf4j-jdk14:2.0.3" + implementation "io.netty:netty-all:4.1.85.Final" + implementation "org.slf4j:slf4j-jdk14:2.0.5" implementation "com.google.inject:guice:$guiceVersion" implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" - implementation "org.glassfish:javax.json:1.1.4" + implementation "org.glassfish:jakarta.json:1.1.6" implementation "org.eclipse.jetty:jetty-server:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlet:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlets:$jettyVersion" @@ -65,26 +65,26 @@ dependencies { implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" - implementation "org.liquibase:liquibase-core:4.16.1" - implementation "com.sun.mail:javax.mail:1.6.2" + implementation "org.liquibase:liquibase-core:4.17.2" + implementation "com.sun.mail:jakarta.mail:1.6.7" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) implementation "org.jxls:jxls-poi:1.0.16" // needs upgrade (wait for jexl 4) implementation "org.apache.velocity:velocity:1.7" // needs upgrade implementation "org.apache.velocity:velocity-tools:2.0" // needs upgrade implementation "org.apache.commons:commons-collections4:4.4" - implementation "org.mnode.ical4j:ical4j:3.2.5" + implementation "org.mnode.ical4j:ical4j:3.2.7" implementation "org.locationtech.spatial4j:spatial4j:0.8" implementation "org.locationtech.jts:jts-core:1.19.0" implementation "net.java.dev.jna:jna-platform:5.12.1" - implementation "com.github.jnr:jnr-posix:3.1.15" + implementation "com.github.jnr:jnr-posix:3.1.16" implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "javax.xml.bind:jaxb-api:2.3.1" implementation "com.sun.xml.bind:jaxb-core:3.0.2" // needs upgrade implementation "com.sun.xml.bind:jaxb-impl:3.0.2" // needs upgrade implementation "javax.activation:activation:1.1.1" - implementation "com.amazonaws:aws-java-sdk-sns:1.12.314" + implementation "com.amazonaws:aws-java-sdk-sns:1.12.349" implementation "org.apache.kafka:kafka-clients:3.3.1" - implementation ("com.google.firebase:firebase-admin:9.0.0") { + implementation ("com.google.firebase:firebase-admin:9.1.1") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' } testImplementation "junit:junit:4.13.2" diff --git a/src/main/java/org/traccar/storage/DatabaseModule.java b/src/main/java/org/traccar/storage/DatabaseModule.java index 71bf84b34..3e3483818 100644 --- a/src/main/java/org/traccar/storage/DatabaseModule.java +++ b/src/main/java/org/traccar/storage/DatabaseModule.java @@ -24,7 +24,7 @@ import liquibase.Liquibase; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.exception.LiquibaseException; -import liquibase.resource.FileSystemResourceAccessor; +import liquibase.resource.DirectoryResourceAccessor; import liquibase.resource.ResourceAccessor; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -80,7 +80,7 @@ public class DatabaseModule extends AbstractModule { if (config.hasKey(Keys.DATABASE_CHANGELOG)) { - ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); + ResourceAccessor resourceAccessor = new DirectoryResourceAccessor(new File(".")); Database database = DatabaseFactory.getInstance().openDatabase( config.getString(Keys.DATABASE_URL), -- cgit v1.2.3 From 36579b977f34dd5393aef19b63160fb1ffba09f4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 2 Dec 2022 16:38:38 -0800 Subject: Fix DualCam init response --- src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index e646c4e4a..d03f7648d 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -84,7 +84,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { response.writeShort(file.length()); response.writeCharSequence(file, StandardCharsets.US_ASCII); } else { - response.writeShort(MSG_COMPLETE); + response.writeShort(MSG_INIT); } channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } -- cgit v1.2.3 From 2fcd5c8decf9f329c3e2325ce950d2b0493b29ab Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 2 Dec 2022 17:22:46 -0800 Subject: Decode Cellocator CR300 reason --- src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index ecd09a2d8..07f7f1692 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -119,7 +119,7 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, buf.readUnsignedByte() & 0x0f); buf.readUnsignedByte(); // operator / configuration flags - buf.readUnsignedByte(); // reason data + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("mode", buf.readUnsignedByte()); -- cgit v1.2.3 From b2f021bc447884d85c9fbcce93bb708d3702d1d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 4 Dec 2022 10:38:38 -0800 Subject: Improve permissions check --- .../traccar/api/security/PermissionsService.java | 32 ++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 37bb6fd72..4421572d7 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -120,25 +120,35 @@ public class PermissionsService { } } - public void checkEdit(long userId, Object object, boolean addition) throws StorageException, SecurityException { + public void checkEdit(long userId, BaseModel object, boolean addition) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { checkEdit(userId, object.getClass(), addition); - boolean denied = false; if (object instanceof GroupedModel) { - long groupId = ((GroupedModel) object).getGroupId(); - if (groupId > 0) { - checkPermission(Group.class, userId, groupId); + GroupedModel after = ((GroupedModel) object); + if (after.getGroupId() > 0) { + GroupedModel before = null; + if (!addition) { + before = storage.getObject(after.getClass(), new Request( + new Columns.Include("groupId"), new Condition.Equals("id", object.getId()))); + } + if (before == null || before.getGroupId() != after.getGroupId()) { + checkPermission(Group.class, userId, after.getGroupId()); + } } } if (object instanceof ScheduledModel) { - long calendarId = ((ScheduledModel) object).getCalendarId(); - if (calendarId > 0) { - denied = storage.getPermissions(User.class, userId, Calendar.class, calendarId).isEmpty(); + ScheduledModel after = ((ScheduledModel) object); + if (after.getCalendarId() > 0) { + ScheduledModel before = null; + if (!addition) { + before = storage.getObject(after.getClass(), new Request( + new Columns.Include("calendarId"), new Condition.Equals("id", object.getId()))); + } + if (before == null || before.getCalendarId() != after.getCalendarId()) { + checkPermission(Calendar.class, userId, after.getCalendarId()); + } } } - if (denied) { - throw new SecurityException("Write access denied"); - } } } -- cgit v1.2.3 From 95ee5109d56fdcb01bcf8f1f620d00654fafb4a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 6 Dec 2022 17:00:10 -0800 Subject: Fix DMT Bolt2 alarms --- src/main/java/org/traccar/protocol/DmtProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java index 0fd83f503..320aa1b60 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java @@ -184,9 +184,9 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - if (!BitUtil.check(input, 1)) { + if (!BitUtil.check(status, 1)) { position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - } else if (BitUtil.check(input, 6)) { + } else if (BitUtil.check(status, 6)) { position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); } -- cgit v1.2.3 From 5e6761cf355110dc91b5bf7847f57570473a19b2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Dec 2022 12:55:27 -0800 Subject: Fix Teltonika temperature (fix #4993) --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 89af20b22..c63d74c9c 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -234,10 +234,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); - register(72, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 1, b.readShort() * 0.1)); - register(73, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 2, b.readShort() * 0.1)); - register(74, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 3, b.readShort() * 0.1)); - register(75, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 4, b.readShort() * 0.1)); + register(72, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 1, b.readInt() * 0.1)); + register(73, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 2, b.readInt() * 0.1)); + register(74, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 3, b.readInt() * 0.1)); + register(75, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 4, b.readInt() * 0.1)); register(78, null, (p, b) -> { long driverUniqueId = b.readLong(); if (driverUniqueId > 0) { -- cgit v1.2.3 From 4b9ff1bd206adb826262acd4e3daf5c962518d7c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Dec 2022 09:27:17 -0800 Subject: Fix cache updates --- src/main/java/org/traccar/session/cache/CacheManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index dc7382223..9d2350012 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -227,6 +227,15 @@ public class CacheManager implements BroadcastInterface { broadcastService.invalidateObject(true, object.getClass(), object.getId()); } + if (object instanceof Server) { + invalidateServer(); + return; + } + if (object instanceof User) { + invalidateUsers(); + return; + } + boolean invalidate = false; var before = getObject(object.getClass(), object.getId()); if (before == null) { -- cgit v1.2.3 From 867e800009bf361c3da9306bc5a9e3f1fab43869 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 11 Dec 2022 09:10:11 -0800 Subject: Improve T55 IP identification --- src/main/java/org/traccar/protocol/T55ProtocolDecoder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 90382439e..51f06a801 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -379,11 +379,12 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } deviceSession = getDeviceSession(channel, remoteAddress, id); sentence = sentence.substring(index); - } else if (remoteAddress instanceof InetSocketAddress) { - String host = ((InetSocketAddress) remoteAddress).getHostString(); - deviceSession = getDeviceSession(channel, remoteAddress, host); } else { deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null && remoteAddress instanceof InetSocketAddress) { + String host = ((InetSocketAddress) remoteAddress).getHostString(); + deviceSession = getDeviceSession(channel, remoteAddress, host); + } } if (sentence.startsWith("$PGID")) { -- 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 'src/main/java/org') 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 1a39c3ed8ddf78acdc50e25aae76f647243f2a00 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Dec 2022 13:07:35 -0800 Subject: Fix imports --- src/main/java/org/traccar/MainModule.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f3d04f634..a8f895d3b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -42,7 +42,26 @@ import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; import org.traccar.forward.PositionForwarderKafka; import org.traccar.forward.PositionForwarderUrl; -import org.traccar.geocoder.*; +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.LocationIqGeocoder; +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.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; -- cgit v1.2.3 From a87c77da9e8d39856e2a16ae3d3aa385e068a1e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Dec 2022 07:35:58 -0800 Subject: Handle missing user id --- src/main/java/org/traccar/api/AsyncSocketServlet.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 40e1551a1..91a745eeb 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -51,11 +51,12 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { factory.setIdleTimeout(Duration.ofMillis(config.getLong(Keys.WEB_TIMEOUT))); factory.setCreator((req, resp) -> { if (req.getSession() != null) { - long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(objectMapper, connectionManager, storage, userId); - } else { - return null; + Long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); + if (userId != null) { + return new AsyncSocket(objectMapper, connectionManager, storage, userId); + } } + return null; }); } -- cgit v1.2.3 From 64391161c1fb03bd9ff5ea30749b4e00230fa8aa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Dec 2022 06:59:53 -0800 Subject: Handle Teltonika heartbeat --- src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java | 4 ++-- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 8 +++++--- src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java | 2 +- .../java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 4 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java index c30fee6e3..3a0962584 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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,7 +30,7 @@ public class TeltonikaFrameDecoder extends BaseFrameDecoder { ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { while (buf.isReadable() && buf.getByte(buf.readerIndex()) == (byte) 0xff) { - buf.skipBytes(1); + return buf.readRetainedSlice(1); } if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index c63d74c9c..929eca8aa 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -647,9 +647,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - if (buf.getUnsignedShort(0) > 0) { + if (buf.readableBytes() == 1 && buf.readUnsignedByte() == 0xff) { + return null; + } else if (buf.getUnsignedShort(0) > 0) { parseIdentification(channel, remoteAddress, buf); } else { buf.skipBytes(4); @@ -659,7 +661,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedShort(); // length buf.readUnsignedShort(); // packet id diff --git a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java index d5c7fcdb0..adc768460 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java @@ -11,7 +11,7 @@ public class TeltonikaFrameDecoderTest extends ProtocolTest { var decoder = inject(new TeltonikaFrameDecoder()); verifyFrame( - binary("000F313233343536373839303132333435"), + binary("ff"), decoder.decode(null, null, binary("FF000F313233343536373839303132333435"))); verifyFrame( diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 188c4b6eb..ba64642f2 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -125,6 +125,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "000000000000004a08010000015ebc1da508002411926621f15246010b00b913005e000f06ef01f00150011505c800450108b5000bb6000642381b18005ecd0318ce19cd430f5844000001f1000061a900010000c8e1")); + verifyNull(decoder, binary( + "ff")); + decoder.setExtended(true); verifyPositions(decoder, false, binary( -- cgit v1.2.3 From 3b36ac38a0c4e193ea8085eb5556dffd8205bb17 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Dec 2022 16:08:25 -0800 Subject: Handle motion fluctuation (fix #5000) --- schema/changelog-5.6.xml | 17 +++++++++++++++++ schema/changelog-master.xml | 1 + .../org/traccar/handler/events/MotionEventHandler.java | 2 +- src/main/java/org/traccar/model/Device.java | 13 +++++++++++++ .../java/org/traccar/reports/common/ReportUtils.java | 4 +++- .../java/org/traccar/session/state/MotionProcessor.java | 10 ++++++++-- .../java/org/traccar/session/state/MotionState.java | 13 +++++++++++++ .../traccar/handler/events/MotionEventHandlerTest.java | 7 +++---- tools/recover.py | 2 +- 9 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 schema/changelog-5.6.xml (limited to 'src/main/java/org') diff --git a/schema/changelog-5.6.xml b/schema/changelog-5.6.xml new file mode 100644 index 000000000..335f7b3a8 --- /dev/null +++ b/schema/changelog-5.6.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index cc39c5c41..0835918c9 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -36,5 +36,6 @@ + diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 1b9763c41..c406bd935 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -75,7 +75,7 @@ public class MotionEventHandler extends BaseEventHandler { state.toDevice(device); try { storage.updateObject(device, new Request( - new Columns.Include("motionState", "motionTime", "motionDistance"), + new Columns.Include("motionStreak", "motionState", "motionTime", "motionDistance"), new Condition.Equals("id", device.getId()))); } catch (StorageException e) { LOGGER.warn("Update device motion error", e); diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 7728172cb..b8c87921d 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -162,6 +162,19 @@ public class Device extends GroupedModel implements Disableable { this.expirationTime = expirationTime; } + private boolean motionStreak; + + @QueryIgnore + @JsonIgnore + public boolean getMotionStreak() { + return motionStreak; + } + + @JsonIgnore + public void setMotionStreak(boolean motionStreak) { + this.motionStreak = motionStreak; + } + private boolean motionState; @QueryIgnore diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 120dadcf5..a7c420095 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -354,7 +354,9 @@ public class ReportUtils { boolean trips = reportClass.equals(TripReportItem.class); MotionState motionState = new MotionState(); - motionState.setMotionState(isMoving(positions, 0, tripsConfig)); + boolean initialValue = isMoving(positions, 0, tripsConfig); + motionState.setMotionStreak(initialValue); + motionState.setMotionState(initialValue); boolean detected = trips == motionState.getMotionState(); int startEventIndex = detected ? 0 : -1; diff --git a/src/main/java/org/traccar/session/state/MotionProcessor.java b/src/main/java/org/traccar/session/state/MotionProcessor.java index b9d706492..a1737a739 100644 --- a/src/main/java/org/traccar/session/state/MotionProcessor.java +++ b/src/main/java/org/traccar/session/state/MotionProcessor.java @@ -59,6 +59,7 @@ public final class MotionProcessor { String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; Event event = new Event(eventType, position); + state.setMotionStreak(newState); state.setMotionTime(null); state.setMotionDistance(0); state.setEvent(event); @@ -67,8 +68,13 @@ public final class MotionProcessor { } } else { state.setMotionState(newState); - state.setMotionTime(position.getFixTime()); - state.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); + if (state.getMotionStreak() == newState) { + state.setMotionTime(null); + state.setMotionDistance(0); + } else { + state.setMotionTime(position.getFixTime()); + state.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); + } } } diff --git a/src/main/java/org/traccar/session/state/MotionState.java b/src/main/java/org/traccar/session/state/MotionState.java index e3ce58ab2..6c917ad16 100644 --- a/src/main/java/org/traccar/session/state/MotionState.java +++ b/src/main/java/org/traccar/session/state/MotionState.java @@ -24,6 +24,7 @@ public class MotionState { public static MotionState fromDevice(Device device) { MotionState state = new MotionState(); + state.motionStreak = device.getMotionStreak(); state.motionState = device.getMotionState(); state.motionTime = device.getMotionTime(); state.motionDistance = device.getMotionDistance(); @@ -31,6 +32,7 @@ public class MotionState { } public void toDevice(Device device) { + device.setMotionStreak(motionStreak); device.setMotionState(motionState); device.setMotionTime(motionTime); device.setMotionDistance(motionDistance); @@ -42,6 +44,17 @@ public class MotionState { return changed; } + private boolean motionStreak; + + public boolean getMotionStreak() { + return motionStreak; + } + + public void setMotionStreak(boolean motionStreak) { + this.motionStreak = motionStreak; + changed = true; + } + private boolean motionState; public boolean getMotionState() { diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 25c766b51..b77676dc8 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -1,6 +1,5 @@ package org.traccar.handler.events; -import org.junit.Ignore; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Event; @@ -62,7 +61,6 @@ public class MotionEventHandlerTest extends BaseTest { verifyState(state, false, 0); } - @Ignore @Test public void testMotionFluctuation() throws ParseException { TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false, 0.01); @@ -87,11 +85,11 @@ public class MotionEventHandlerTest extends BaseTest { MotionProcessor.updateState(state, position("2017-01-01 00:04:00", true, 1000, null), true, tripsConfig); assertNull(state.getEvent()); - verifyState(state, true, 1000); + verifyState(state, true, 0); MotionProcessor.updateState(state, position("2017-01-01 00:06:00", true, 2000, null), true, tripsConfig); assertNull(state.getEvent()); - verifyState(state, true, 2000); + verifyState(state, true, 0); } @Test @@ -99,6 +97,7 @@ public class MotionEventHandlerTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false, 0.01); MotionState state = new MotionState(); + state.setMotionStreak(true); state.setMotionState(true); MotionProcessor.updateState(state, position("2017-01-01 00:00:00", false, 100, true), false, tripsConfig); diff --git a/tools/recover.py b/tools/recover.py index dfa94c978..32e3f8721 100755 --- a/tools/recover.py +++ b/tools/recover.py @@ -48,5 +48,5 @@ for session in protocols: s.connect(("localhost", int(port))) for message in messages[session]: s.send(binascii.unhexlify(message)) - time.sleep(0.5) + time.sleep(0.1) s.close() -- cgit v1.2.3 From bc2eb6ab65493a18b262ffe49fe79b540862c5db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 15 Dec 2022 07:20:10 -0800 Subject: Decode HHD batch location --- .../traccar/protocol/HuabaoProtocolDecoder.java | 22 +++++++++++++--------- .../protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 27a5094a0..cb747fc2e 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -57,6 +57,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TERMINAL_CONTROL = 0x8105; public static final int MSG_TERMINAL_AUTH = 0x0102; public static final int MSG_LOCATION_REPORT = 0x0200; + public static final int MSG_LOCATION_BATCH_2 = 0x0210; public static final int MSG_ACCELERATION = 0x2070; public static final int MSG_LOCATION_REPORT_2 = 0x5501; public static final int MSG_LOCATION_REPORT_BLIND = 0x5502; @@ -243,11 +244,11 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return decodeLocation2(deviceSession, buf, type); - } else if (type == MSG_LOCATION_BATCH) { + } else if (type == MSG_LOCATION_BATCH || type == MSG_LOCATION_BATCH_2) { sendGeneralResponse(channel, remoteAddress, id, type, index); - return decodeLocationBatch(deviceSession, buf); + return decodeLocationBatch(deviceSession, buf, type); } else if (type == MSG_TIME_SYNC_REQUEST) { @@ -681,21 +682,24 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return position; } - private List decodeLocationBatch(DeviceSession deviceSession, ByteBuf buf) { + private List decodeLocationBatch(DeviceSession deviceSession, ByteBuf buf, int type) { List positions = new LinkedList<>(); - int count = buf.readUnsignedShort(); - int locationType = buf.readUnsignedByte(); + int locationType = 0; + if (type == MSG_LOCATION_BATCH) { + buf.readUnsignedShort(); // count + locationType = buf.readUnsignedByte(); + } - for (int i = 0; i < count; i++) { - int endIndex = buf.readUnsignedShort() + buf.readerIndex(); - Position position = decodeLocation(deviceSession, buf); + while (buf.readableBytes() > 2) { + int length = type == MSG_LOCATION_BATCH_2 ? buf.readUnsignedByte() : buf.readUnsignedShort(); + ByteBuf fragment = buf.readSlice(length); + Position position = decodeLocation(deviceSession, fragment); if (locationType > 0) { position.set(Position.KEY_ARCHIVE, true); } positions.add(position); - buf.readerIndex(endIndex); } return positions; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 9bbd375dc..2b41f49df 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyPositions(decoder, binary( + "7E021001A2010036526447000A3B00000000000000010158F52206C916B0000000000000161118110121661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110122661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110123661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110124661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B00000000000001611181101253B00000000000000010158F52206C916B0000000000000161118110126661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110127661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B0000000000000161118110128F57E")); + verifyAttribute(decoder, binary( "7e02000042012291302260198f00000000800c012300d2651605ff3188001e0000000022102510310003020000a70400000000ac040000012ce5020003e60b03bc572900ce2eef183200e7030000005c7e"), Position.PREFIX_TEMP + 3, -17.094117647058823); -- cgit v1.2.3 From 1c791638d74998b4451b3c6290c04c46ecd1a9c5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Dec 2022 20:27:29 -0800 Subject: Remove finalizer --- src/main/java/org/traccar/forward/EventForwarderKafka.java | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/EventForwarderKafka.java b/src/main/java/org/traccar/forward/EventForwarderKafka.java index db97d22de..e65c3a51b 100644 --- a/src/main/java/org/traccar/forward/EventForwarderKafka.java +++ b/src/main/java/org/traccar/forward/EventForwarderKafka.java @@ -43,12 +43,6 @@ public class EventForwarderKafka implements EventForwarder { topic = config.getString(Keys.EVENT_FORWARD_TOPIC); } - @SuppressWarnings("deprecation") - @Override - protected void finalize() { - producer.close(); - } - @Override public void forward(EventData eventData, ResultHandler resultHandler) { try { -- cgit v1.2.3 From ddf72b364323ed3f787fd41c5d5126c3521b96b7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Dec 2022 20:32:01 -0800 Subject: Throw on invalid coordinates --- src/main/java/org/traccar/model/Position.java | 10 ++++++---- .../java/org/traccar/protocol/GlobalstarProtocolDecoder.java | 12 ++++-------- .../java/org/traccar/protocol/BceProtocolDecoderTest.java | 12 +++++++++++- .../org/traccar/protocol/GlobalstarProtocolDecoderTest.java | 2 +- 4 files changed, 22 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 2b743433a..1286db5f2 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -227,9 +227,10 @@ public class Position extends Message { } public void setLatitude(double latitude) { - if (latitude >= -90 && latitude <= 90) { - this.latitude = latitude; + if (latitude < -90 || latitude > 90) { + throw new IllegalArgumentException("Latitude out of range"); } + this.latitude = latitude; } private double longitude; @@ -239,9 +240,10 @@ public class Position extends Message { } public void setLongitude(double longitude) { - if (longitude >= -180 && longitude <= 180) { - this.longitude = longitude; + if (longitude < -180 || longitude > 180) { + throw new IllegalArgumentException("Longitude out of range"); } + this.longitude = longitude; } private double altitude; // value in meters diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java index e537edf1d..0ddb95c14 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java @@ -151,15 +151,11 @@ public class GlobalstarProtocolDecoder extends BaseHttpProtocolDecoder { position.setCourse(BitUtil.from(flags, 5) * 45); - position.setLatitude(buf.readUnsignedMedium() * 90.0 / (1 << 23)); - if (position.getLatitude() > 90) { - position.setLatitude(position.getLatitude() - 180); - } + double latitude = buf.readUnsignedMedium() * 90.0 / (1 << 23); + position.setLatitude(latitude > 90 ? latitude - 180 : latitude); - position.setLongitude(buf.readUnsignedMedium() * 180.0 / (1 << 23)); - if (position.getLongitude() > 180) { - position.setLongitude(position.getLongitude() - 360); - } + double longitude = buf.readUnsignedMedium() * 180.0 / (1 << 23); + position.setLongitude(longitude > 180 ? longitude - 360 : longitude); int speed = buf.readUnsignedByte(); position.setSpeed(UnitsConverter.knotsFromKph(speed)); diff --git a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java index 89ab64cd3..1d980b7e5 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java @@ -1,19 +1,29 @@ package org.traccar.protocol; +import org.junit.Ignore; import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Position; public class BceProtocolDecoderTest extends ProtocolTest { + @Ignore @Test - public void testDecode() throws Exception { + public void testDecodeFail() throws Exception { var decoder = inject(new BceProtocolDecoder(null)); + // Needs to be fixed verifyPositions(decoder, binary( "18ed450cf3140300c800a53a62972f7bde03c0ffffc0814000e03e354135e34b42121c55fb0000000000d18c060103025d19ab00540000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c400000000000000010104080162a72f7bde03c0ffffc0814000ef3e8e4431e34b42061c54fc0000000000d18c060103025d19ab00540000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c400000000000000010100000053")); + } + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new BceProtocolDecoder(null)); + verifyNull(decoder, binary( "3ab90b71bc1503000300c10bff11")); diff --git a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java index f0ba813ca..730d4bb60 100644 --- a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java @@ -29,7 +29,7 @@ public class GlobalstarProtocolDecoderTest extends ProtocolTest { "0-2682225", "1585105370", "N", - "0x8EFE2D97DDEA420018", + "0x00C583EACD37210A00", "", ""))); -- cgit v1.2.3 From 82a6fc308efde0e274b143dd2f5261c30774c3fe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 19 Dec 2022 05:49:00 -0800 Subject: Support JXYD JX08 data --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 7 +++++++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index cb747fc2e..60477af8f 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -455,6 +455,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x02: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); break; + case 0x2b: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); + break; case 0x30: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); break; @@ -588,6 +591,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0xF3: + position.set(Position.KEY_ARMED, buf.readUnsignedByte() > 0); + break; case 0xFE: if (length == 1) { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); @@ -626,6 +632,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } break; default: + System.out.println("subtype " + String.format("%x", subtype)); break; } buf.readerIndex(endIndex); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 2b41f49df..13b9322c0 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyPosition(decoder, binary( + "7E020000FE069223000241002E00000000000C0003015A98F806C8A1260013000000E622082617464401040000017F02020001030200002504000000002A0200002B0400000000300117310112E306000005890000F3B4000202000000030202F2000402375F00050400000000000602000C000702000C000801320009020072000B020035000C020050000D020176000E0122000F018A00501B4C46504D34414350584731413337303937000000000000000000000052040000000C01000200010101040000000001020200010103040000000101040203E7010C02000E010D020000010E02059B010F020072011002387001110200000112020000011302000001140200000116020000D17E")); + verifyPositions(decoder, binary( "7E021001A2010036526447000A3B00000000000000010158F52206C916B0000000000000161118110121661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110122661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110123661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110124661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B00000000000001611181101253B00000000000000010158F52206C916B0000000000000161118110126661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110127661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B0000000000000161118110128F57E")); -- cgit v1.2.3 From 0a8273d87ab5fd4270aab6000d6cefa1472bb024 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 20 Dec 2022 15:47:22 -0800 Subject: Watch general alarm (fix #5006) --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index a71c5606d..142d1b64f 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -263,6 +263,9 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); if (type.startsWith("AL")) { + if (position != null) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } sendResponse(channel, id, index, "AL"); } -- cgit v1.2.3 From b9cc31bf3ab278df45fa90f6481f929e325326f0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 20 Dec 2022 16:25:24 -0800 Subject: Improve MD500S decoding --- .../org/traccar/protocol/MeitrackProtocolDecoder.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 1935b2c2a..82c8f0087 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -524,12 +524,19 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - if (buf.getUnsignedByte(buf.readerIndex()) == 0xFE) { - buf.readUnsignedShort(); // extension id - } else { - buf.readUnsignedByte(); // id + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0xFE31: + buf.readUnsignedByte(); // alarm protocol + buf.readUnsignedByte(); // alarm type + buf.skipBytes(length - 2); + break; + default: + buf.skipBytes(length); + break; } - buf.skipBytes(buf.readUnsignedByte()); // value } positions.add(position); -- cgit v1.2.3 From a7fb4825f1a756b913024c07c78afe626022b8dd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Dec 2022 15:46:10 -0800 Subject: Add test geocoder --- debug.xml | 2 ++ src/main/java/org/traccar/MainModule.java | 4 +++ .../java/org/traccar/geocoder/TestGeocoder.java | 36 ++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/main/java/org/traccar/geocoder/TestGeocoder.java (limited to 'src/main/java/org') diff --git a/debug.xml b/debug.xml index 7b5c1acff..2569bb8cd 100644 --- a/debug.xml +++ b/debug.xml @@ -10,6 +10,8 @@ true true + test + ./target/media true diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a8f895d3b..078573a60 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -61,6 +61,7 @@ import org.traccar.geocoder.MapmyIndiaGeocoder; import org.traccar.geocoder.NominatimGeocoder; import org.traccar.geocoder.OpenCageGeocoder; import org.traccar.geocoder.PositionStackGeocoder; +import org.traccar.geocoder.TestGeocoder; import org.traccar.geocoder.TomTomGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; @@ -181,6 +182,9 @@ public class MainModule extends AbstractModule { int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); Geocoder geocoder; switch (type) { + case "test": + geocoder = new TestGeocoder(); + break; case "nominatim": geocoder = new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); break; diff --git a/src/main/java/org/traccar/geocoder/TestGeocoder.java b/src/main/java/org/traccar/geocoder/TestGeocoder.java new file mode 100644 index 000000000..259f13c6c --- /dev/null +++ b/src/main/java/org/traccar/geocoder/TestGeocoder.java @@ -0,0 +1,36 @@ +/* + * 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 org.traccar.database.StatisticsManager; + +public class TestGeocoder implements Geocoder { + + @Override + public void setStatisticsManager(StatisticsManager statisticsManager) { + } + + @Override + public String getAddress(double latitude, double longitude, ReverseGeocoderCallback callback) { + String address = String.format("Location %f, %f", latitude, longitude); + if (callback != null) { + callback.onSuccess(address); + return null; + } + return address; + } + +} -- cgit v1.2.3 From 13156bb9d7c92dac8bd775e936946b3de08f0732 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 22 Dec 2022 11:36:24 -0800 Subject: Remove subtype logging --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 60477af8f..cb32e4a38 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -632,7 +632,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } break; default: - System.out.println("subtype " + String.format("%x", subtype)); break; } buf.readerIndex(endIndex); -- cgit v1.2.3 From 81aac9fbdd85db06b4f5162b39edd3c039cc7dec Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 22 Dec 2022 13:11:51 -0800 Subject: Add JXYD JX06 parameters --- .../traccar/protocol/HuabaoProtocolDecoder.java | 61 +++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index cb32e4a38..f08c2afa4 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -592,7 +592,66 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; case 0xF3: - position.set(Position.KEY_ARMED, buf.readUnsignedByte() > 0); + while (buf.readerIndex() < endIndex) { + int extendedType = buf.readUnsignedShort(); + int extendedLength = buf.readUnsignedByte(); + switch (extendedType) { + case 0x0002: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + break; + case 0x0003: + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + break; + case 0x0004: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + break; + case 0x0005: + position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100); + break; + case 0x0007: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.1); + break; + case 0x0008: + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedShort() * 0.1); + break; + case 0x0009: + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedShort() - 40); + break; + case 0x000B: + position.set("intakePressure", buf.readUnsignedShort()); + break; + case 0x000C: + position.set("intakeTemp", buf.readUnsignedShort() - 40); + break; + case 0x000D: + position.set("intakeFlow", buf.readUnsignedShort()); + break; + case 0x000E: + position.set(Position.KEY_THROTTLE, buf.readUnsignedShort() * 100 / 255); + break; + case 0x0050: + position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); + break; + case 0x0100: + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 0.1); + break; + case 0x0102: + position.set("tripFuel", buf.readUnsignedShort() * 0.1); + break; + case 0x0112: + position.set("hardAccelerationCount", buf.readUnsignedShort()); + break; + case 0x0113: + position.set("hardDecelerationCount", buf.readUnsignedShort()); + break; + case 0x0114: + position.set("hardCorneringCount", buf.readUnsignedShort()); + break; + default: + buf.skipBytes(extendedLength); + break; + } + } break; case 0xFE: if (length == 1) { -- cgit v1.2.3 From fdc1997909043b128b358e4404260b3fbff8c289 Mon Sep 17 00:00:00 2001 From: Svetoslav Batchovski Date: Wed, 21 Dec 2022 22:51:51 +0100 Subject: MQTT EventForwarder added --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 13 ++- .../org/traccar/forward/EventForwarderMqtt.java | 103 +++++++++++++++++++++ 3 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/traccar/forward/EventForwarderMqtt.java (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index a48a07be5..91ba2cd5c 100644 --- a/build.gradle +++ b/build.gradle @@ -84,6 +84,7 @@ dependencies { implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.349" implementation "org.apache.kafka:kafka-clients:3.3.1" + implementation 'com.hivemq:hivemq-mqtt-client:1.3.0' implementation("com.google.firebase:firebase-admin:9.1.1") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' exclude group: 'com.google.cloud', module: 'google-cloud-storage' diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a8f895d3b..55b26010f 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -38,6 +38,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; import org.traccar.forward.EventForwarderKafka; +import org.traccar.forward.EventForwarderMqtt; import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; import org.traccar.forward.PositionForwarderKafka; @@ -322,10 +323,14 @@ public class MainModule extends AbstractModule { @Provides public static EventForwarder provideEventForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - if (config.getString(Keys.EVENT_FORWARD_TYPE).equals("kafka")) { - return new EventForwarderKafka(config, objectMapper); - } else { - return new EventForwarderJson(config, client); + String forwardType = config.getString(Keys.EVENT_FORWARD_TYPE); + switch (forwardType) { + case "kafka": + return new EventForwarderKafka(config, objectMapper); + case "mqtt": + return new EventForwarderMqtt(config, objectMapper); + default: + return new EventForwarderJson(config, client); } } return null; diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java new file mode 100644 index 000000000..dc95cb4e2 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -0,0 +1,103 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.UUID; + +public class EventForwarderMqtt implements EventForwarder { + + private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarderMqtt.class); + private final Mqtt5AsyncClient client; + private final ObjectMapper objectMapper; + + private final String topic; + + public EventForwarderMqtt(Config config, ObjectMapper objectMapper) { + URI url; + try { + url = new URI(config.getString(Keys.EVENT_FORWARD_URL)); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + String userInfo = url.getUserInfo(); + Mqtt5SimpleAuth simpleAuth = null; + if (userInfo != null) { + int delimiter = userInfo.indexOf(':'); + if (delimiter == -1) { + throw new IllegalArgumentException("Wrong credentials. Should be in format \"username:password\""); + } else { + simpleAuth = Mqtt5SimpleAuth.builder() + .username(userInfo.substring(0, delimiter++)) + .password(userInfo.substring(delimiter).getBytes()) + .build(); + } + } + + String host = url.getHost(); + int port = url.getPort(); + client = Mqtt5Client.builder() + .identifier("traccar-" + UUID.randomUUID().toString()) + .serverHost(host) + .serverPort(port) + .simpleAuth(simpleAuth) + .automaticReconnectWithDefaultConfig() + .buildAsync(); + + client.connectWith() + .send() + .whenComplete((message, e) -> { + if (e != null) { + throw new RuntimeException(e); + } + }); + + this.objectMapper = objectMapper; + topic = config.getString(Keys.EVENT_FORWARD_TOPIC); + } + + @Override + public void forward(EventData eventData, ResultHandler resultHandler) { + byte[] payload; + try { + payload = objectMapper.writeValueAsString(eventData).getBytes(); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + return; + } + + client.publishWith() + .topic(topic) + .qos(MqttQos.AT_LEAST_ONCE) + .payload(payload) + .send() + .whenComplete((message, e) -> resultHandler.onResult(e == null, e)); + } + +} -- cgit v1.2.3 From 2e1b77d6aa5a2c2d2e07b29f80c40ec741004819 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 24 Dec 2022 11:41:14 -0800 Subject: Extend Iridium format --- src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java index 0306770b6..0e1c7568b 100644 --- a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -52,7 +52,7 @@ public class Tr20ProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)(dd.d+),") // longitude .number("(d+),") // speed .number("(d+),") // course - .number("(?:NA|[FC]?(-?d+)[^,]*),") // temperature + .number("(?:NA|[BFC]?(-?d+)[^,]*),") // temperature .number("(x{8}),") // status .number("(d+)") // event .any() diff --git a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java index c4513cbdc..e4917c872 100644 --- a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Tr20ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Tr20ProtocolDecoder(null)); + verifyPosition(decoder, text( + "%%m13,L,221221103115,N1237.2271W00801.9500,000,000,B13.1:F0.0,04020000,253,CFG:133.00|")); + verifyPosition(decoder, text( "%%TR20GRANT,L,210602170135,N0951.1733W08356.7672,000,000,C80:F0,00020008,108,CFG:6980.00|")); -- cgit v1.2.3 From 6c8fdbbf5f44db7eb88bc75dbaf89c679aa25cd5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 28 Dec 2022 07:52:24 -0800 Subject: Fix event and ignition --- .../java/org/traccar/protocol/CellocatorProtocolDecoder.java | 10 ++++++---- .../org/traccar/protocol/CellocatorProtocolDecoderTest.java | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index 07f7f1692..3573a95ca 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -119,14 +119,16 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, buf.readUnsignedByte() & 0x0f); buf.readUnsignedByte(); // operator / configuration flags - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + buf.readUnsignedByte(); // reason data + short event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); position.set("mode", buf.readUnsignedByte()); - long input = buf.readUnsignedIntLE(); + long input = buf.readUnsignedInt(); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 3 * 8 + 5)); position.set(Position.KEY_DOOR, BitUtil.check(input, 3 * 8)); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 2 * 8 + 7)); position.set(Position.KEY_CHARGE, BitUtil.check(input, 7)); position.set(Position.KEY_INPUT, input); diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java index 7e96b073b..27cad39a3 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class CellocatorProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,10 @@ public class CellocatorProtocolDecoderTest extends ProtocolTest { var decoder = inject(new CellocatorProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "4d4347500098ab31000856b12b2c041016002c0023b3000021f3f5ffb04c8f0100000000000078dd0004020f716445f75f3b0701126e0200b303000036002538151b0ce607ab"), + Position.KEY_IGNITION, true); + verifyPosition(decoder, binary( "4D43475000856308000004B2DE1F04009E00200100000000696CF7AB002F1A00000000000000325C000402069BFDE70857E22502F41C000036000000DF0B0932100B09DC0719")); -- cgit v1.2.3 From 32d276ee8d3595a9f3290b96ca0b6bdd6140b7b4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 30 Dec 2022 17:03:04 -0800 Subject: Improve JM-LL301 support --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 31 ++++++++++++++++++---- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 4 +++ 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 212b4245f..15588c89b 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -100,7 +100,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_WIFI_3 = 0xA2; // GK310 public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 public static final int MSG_FENCE_MULTI = 0xA4; // GK310 - public static final int MSG_LBS_ALARM = 0xA5; // GK310 + public static final int MSG_LBS_ALARM = 0xA5; // GK310 & JM-LL301 public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 public static final int MSG_OBD = 0x8C; // FM08ABC public static final int MSG_DTC = 0x65; // FM08ABC @@ -209,6 +209,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: + case MSG_LBS_ALARM: return true; default: return false; @@ -334,9 +335,26 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } int mcc = buf.readUnsignedShort(); - int mnc = BitUtil.check(mcc, 15) || type == MSG_GPS_LBS_6 ? buf.readUnsignedShort() : buf.readUnsignedByte(); - int lac = buf.readUnsignedShort(); - long cid = type == MSG_GPS_LBS_6 ? buf.readUnsignedInt() : buf.readUnsignedMedium(); + int mnc; + if (BitUtil.check(mcc, 15) || type == MSG_GPS_LBS_6) { + mnc = buf.readUnsignedShort(); + } else { + mnc = buf.readUnsignedByte(); + } + int lac; + if (type == MSG_LBS_ALARM) { + lac = buf.readInt(); + } else { + lac = buf.readUnsignedShort(); + } + long cid; + if (type == MSG_LBS_ALARM) { + cid = buf.readLong(); + } else if (type == MSG_GPS_LBS_6) { + cid = buf.readUnsignedInt(); + } else { + cid = buf.readUnsignedMedium(); + } position.setNetwork(new Network(CellTower.from(BitUtil.to(mcc, 15), mnc, lac, cid))); @@ -401,6 +419,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_OVERSPEED; case 0x0E: case 0x0F: + case 0x19: return Position.ALARM_LOW_BATTERY; case 0x11: return Position.ALARM_POWER_OFF; @@ -410,6 +429,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_TAMPERING; case 0x14: return Position.ALARM_DOOR; + case 0x18: + return Position.ALARM_REMOVING; case 0x23: return Position.ALARM_FALL_DOWN; case 0x29: @@ -783,7 +804,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type)) { - decodeLbs(position, buf, type, hasStatus(type)); + decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM); } if (hasStatus(type)) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index d1789bb16..9d0716c7d 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "787819a5012ed0000075df000000000098661502050413000019a12b0d0a"), + Position.KEY_ALARM, Position.ALARM_TAMPERING); + verifyAttribute(decoder, binary( "7878131302801900002e42016f000000003a0177ef180d0a"), Position.KEY_POWER, 3.67); -- cgit v1.2.3 From 67964087deaa12557ac3c48b537ee22475f82f5d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 31 Dec 2022 16:46:38 -0800 Subject: Decode G1A cell info --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 7 +++++++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index f08c2afa4..d0bbeebb5 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -571,6 +571,13 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x00CE: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); break; + case 0x00D8: + Network network = new Network(); + network.addCellTower(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedByte(), + buf.readUnsignedShort(), buf.readUnsignedInt())); + position.setNetwork(network); + break; case 0xE1: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 13b9322c0..e91c84d79 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyPosition(decoder, binary( + "7e0200004107904226220608ca0000010000000010031dac0d004864f30000000000002212291003220104000179a7300107310100eb17000300e151000300e304000b00d801041edf340000306b007e")); + verifyPosition(decoder, binary( "7E020000FE069223000241002E00000000000C0003015A98F806C8A1260013000000E622082617464401040000017F02020001030200002504000000002A0200002B0400000000300117310112E306000005890000F3B4000202000000030202F2000402375F00050400000000000602000C000702000C000801320009020072000B020035000C020050000D020176000E0122000F018A00501B4C46504D34414350584731413337303937000000000000000000000052040000000C01000200010101040000000001020200010103040000000101040203E7010C02000E010D020000010E02059B010F020072011002387001110200000112020000011302000001140200000116020000D17E")); -- cgit v1.2.3 From 2ed386ecd1fa6b51cf3115fe6fe4626ebfceea31 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 Jan 2023 15:01:37 -0800 Subject: Handle T55 new line --- src/main/java/org/traccar/protocol/T55ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 51f06a801..3be161fb8 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -365,7 +365,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String sentence = (String) msg; + String sentence = ((String) msg).trim(); DeviceSession deviceSession; -- cgit v1.2.3 From 046076aeb6f0c79bb59ef9aead4ebbc23e286c63 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 3 Jan 2023 09:36:23 -0800 Subject: Handle ZX303 variation --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 15588c89b..ef09677bf 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -803,7 +803,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); } - if (hasLbs(type)) { + if (hasLbs(type) && buf.readableBytes() > 6) { decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM); } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 9d0716c7d..23c29b0d3 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyPosition(decoder, binary( + "78781511170103100e1f9904efe30400a97f88003410ffdd000d0a")); + verifyAttribute(decoder, binary( "787819a5012ed0000075df000000000098661502050413000019a12b0d0a"), Position.KEY_ALARM, Position.ALARM_TAMPERING); -- cgit v1.2.3 From cf5379247a8de3a21016c8a74a6b9c9ac1b81fab Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 5 Jan 2023 09:37:54 -0800 Subject: Fix activity decoding --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index eb5e16de2..0b08badb8 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -272,8 +272,8 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { case 0x31: int i = 1; while (buf.readerIndex() < endIndex) { - position.set("activity" + i + "Time", buf.readUnsignedInt()); - position.set("activity" + i, buf.readUnsignedInt()); + position.set("activity" + i + "Time", buf.readUnsignedIntLE()); + position.set("activity" + i, buf.readUnsignedIntLE()); i += 1; } break; -- cgit v1.2.3 From b76e00c283c79f29ad13fff70b882ae6d3685aa5 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:19:05 +0000 Subject: lbs-for-tlt2h-added --- .../org/traccar/protocol/Tlt2hProtocolDecoder.java | 50 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index 3d219fc09..be8de448d 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -17,6 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.model.CellTower; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; @@ -55,6 +56,12 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_POSITION = new PatternBuilder() .text("#") .number("(?:(dd)|x*)") // cell or voltage + .groupBegin() + .number("#(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+)") // cell id + .groupEnd("?") .text("$GPRMC,") .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) .expression("([AVL]),") // validity @@ -71,6 +78,12 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_WIFI = new PatternBuilder() .text("#") .number("(?:(dd)|x+)") // cell or voltage + .groupBegin() + .number("#(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+)") // cell id + .groupEnd("?") .text("$WIFI,") .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) .expression("[AVL],") // validity @@ -168,17 +181,35 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); } + if (parser.hasNext(4)) { + Network network = new Network(); + network.addCellTower(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())); + position.setNetwork(network); + } + DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); + boolean isPositionValid = parser.next().equals("A"); + position.setValid(isPositionValid); + + if(isPositionValid) { + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble(0)); + position.setCourse(parser.nextDouble(0)); + } else { + parser.skip(8); + } dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); + + if(isPositionValid) { + position.setTime(dateBuilder.getDate()); + } else { + getLastLocation(position, dateBuilder.getDate()); + } } else { continue; @@ -191,11 +222,16 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); + Network network = new Network(); + if (parser.hasNext(4)) { + network.addCellTower(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())); + } + DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); String[] values = parser.next().split(","); - Network network = new Network(); for (int i = 0; i < values.length / 2; i++) { String mac = values[i * 2 + 1].replaceAll("(..)", "$1:").substring(0, 17); network.addWifiAccessPoint(WifiAccessPoint.from(mac, Integer.parseInt(values[i * 2]))); -- cgit v1.2.3 From c1cbda022e33d56e9f77a9e26da59e88061c469f Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:39:34 +0000 Subject: style-fixed --- src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index be8de448d..7976b825f 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -194,7 +194,7 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { boolean isPositionValid = parser.next().equals("A"); position.setValid(isPositionValid); - if(isPositionValid) { + if (isPositionValid) { position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); position.setSpeed(parser.nextDouble(0)); @@ -204,8 +204,8 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { } dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - if(isPositionValid) { + + if (isPositionValid) { position.setTime(dateBuilder.getDate()); } else { getLastLocation(position, dateBuilder.getDate()); -- cgit v1.2.3 From c6e7f17791f5721c994128c8165c71bcb40a02fb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 6 Jan 2023 19:44:12 -0800 Subject: Fix TLT2H LBS decoding --- .../org/traccar/protocol/Tlt2hProtocolDecoder.java | 25 ++++++---------------- 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index 7976b825f..e85bdf9b3 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -191,25 +191,14 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - boolean isPositionValid = parser.next().equals("A"); - position.setValid(isPositionValid); - - if (isPositionValid) { - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - } else { - parser.skip(8); - } + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble(0)); + position.setCourse(parser.nextDouble(0)); dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - if (isPositionValid) { - position.setTime(dateBuilder.getDate()); - } else { - getLastLocation(position, dateBuilder.getDate()); - } + position.setTime(dateBuilder.getDate()); } else { continue; -- cgit v1.2.3 From 397d959f7dc61d9df241e589910ff4e15d5145d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 10 Jan 2023 07:48:06 -0800 Subject: Decode MD500S temperature --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 10 ++++++++++ .../java/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 82c8f0087..bf8ceaf8a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -528,6 +528,16 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); int length = buf.readUnsignedByte(); switch (id) { + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + position.set(Position.PREFIX_TEMP + buf.readUnsignedByte(), buf.readShortLE() * 0.01); + break; case 0xFE31: buf.readUnsignedByte(); // alarm protocol buf.readUnsignedByte(); // alarm type diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 67b83ebd9..ce0a1e922 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyPositions(decoder, binary( + "24246a3138312c3836343238313034313930383330332c4343452c00000000010093001f000505000600070714001502090800000900000a00000b0000160a001706001904001ad90440230006023279570103305ccc0604f536492b0c510300000d495701001c014000000b0e0ccc010000922781abb90c00002a030034212b03008b082c030053082d03009e082e030034212f030034213003003421310300342149090400000000000000004b07010104574946492a36310d0a")); + verifyPositions(decoder, binary( "2424423233322c3836323039303035303030323831332c4343452c0400000003004400110004050006000700fe6962060800000900000a00000b00001aef044023000602d65fbcfd03173b9c0804cc76ae2a0c14ae1b000d00aa0d001c01000000014b030101003f00100004050006000700fe695f060800000900000a00000b00001aea044016000502d65fbcfd03173b9c0804cf76ae2a0c14ae1b000d03aa0d00014b030101003f00100004050006000700fe695f060800000900000a00000b00001aed044001000502d65fbcfd03173b9c0804d076ae2a0c14ae1b000d04aa0d00014b030101002a30460d0a")); -- cgit v1.2.3 From ec13d084baa823da3a520bc1a69178e58138abe3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 11 Jan 2023 16:37:43 -0800 Subject: Fix SQL query --- src/main/java/org/traccar/storage/query/Order.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/storage/query/Order.java b/src/main/java/org/traccar/storage/query/Order.java index b41f145e9..f10970381 100644 --- a/src/main/java/org/traccar/storage/query/Order.java +++ b/src/main/java/org/traccar/storage/query/Order.java @@ -27,7 +27,7 @@ public class Order { public Order(String column, boolean descending, int limit) { this.column = column; - this.descending = false; + this.descending = descending; this.limit = limit; } -- cgit v1.2.3 From 922f2f26f880c92b984435987319d46750d929a0 Mon Sep 17 00:00:00 2001 From: e-macgregor <122734173+e-macgregor@users.noreply.github.com> Date: Sun, 15 Jan 2023 08:29:04 -0600 Subject: Added missing "StatusReq" --- src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index b298adc5a..a4faacf13 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -99,7 +99,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_REBOOT_DEVICE: return formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, prefix + "CMD;%s;02;\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;StatusReq\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { return formatCommand(command, prefix + "CMD;%s;02;Enable%s\r", -- cgit v1.2.3 From 1417098fa45a3060f17e0cca6d8226b12e7f174e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 15 Jan 2023 17:37:20 -0800 Subject: Remove default admin --- schema/changelog-4.0-clean.xml | 8 -------- src/main/java/org/traccar/api/resource/ServerResource.java | 8 ++++++++ src/main/java/org/traccar/api/resource/SessionResource.java | 5 ++++- src/main/java/org/traccar/api/resource/UserResource.java | 5 +++++ src/main/java/org/traccar/helper/model/UserUtil.java | 11 +++++++++++ src/main/java/org/traccar/model/Server.java | 12 ++++++++++++ src/main/java/org/traccar/storage/query/Request.java | 6 +++--- 7 files changed, 43 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/schema/changelog-4.0-clean.xml b/schema/changelog-4.0-clean.xml index f3f814eba..b4d8ac0ba 100644 --- a/schema/changelog-4.0-clean.xml +++ b/schema/changelog-4.0-clean.xml @@ -620,14 +620,6 @@ - - - - - - - - diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index e7f0b93ca..4b7ee9189 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -16,6 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.helper.model.UserUtil; import org.traccar.mail.MailManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; @@ -65,6 +66,13 @@ public class ServerResource extends BaseResource { server.setEmailEnabled(mailManager.getEmailEnabled()); server.setGeocoderEnabled(geocoder != null); User user = permissionsService.getUser(getUserId()); + if (user != null) { + if (user.getAdministrator()) { + server.setStorageSpace(Log.getStorageSpace()); + } + } else { + server.setNewServer(UserUtil.isEmpty(storage)); + } if (user != null && user.getAdministrator()) { server.setStorageSpace(Log.getStorageSpace()); } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 1e984fbd0..7025d5fa7 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -110,7 +110,10 @@ public class SessionResource extends BaseResource { } else { - return permissionsService.getUser(userId); + User user = permissionsService.getUser(userId); + if (user != null) { + return user; + } } diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 91875ef51..e41ebbe61 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -19,6 +19,7 @@ import org.traccar.api.BaseObjectResource; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.LogAction; +import org.traccar.helper.model.UserUtil; import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.User; @@ -98,6 +99,10 @@ public class UserResource extends BaseObjectResource { } } + if (UserUtil.isEmpty(storage)) { + entity.setAdministrator(true); + } + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); storage.updateObject(entity, new Request( new Columns.Include("hashedPassword", "salt"), diff --git a/src/main/java/org/traccar/helper/model/UserUtil.java b/src/main/java/org/traccar/helper/model/UserUtil.java index 9919e1d95..9f93afeae 100644 --- a/src/main/java/org/traccar/helper/model/UserUtil.java +++ b/src/main/java/org/traccar/helper/model/UserUtil.java @@ -17,6 +17,11 @@ package org.traccar.helper.model; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import java.util.TimeZone; @@ -25,6 +30,12 @@ public final class UserUtil { private UserUtil() { } + public static boolean isEmpty(Storage storage) throws StorageException { + return storage.getObjects(User.class, new Request( + new Columns.Include("id"), + new Order("id", false, 1))).isEmpty(); + } + public static String getDistanceUnit(Server server, User user) { return lookupStringAttribute(server, user, "distanceUnit", "km"); } diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 9e248e7bb..73645721b 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -249,4 +249,16 @@ public class Server extends ExtendedModel implements UserRestrictions { this.storageSpace = storageSpace; } + private boolean newServer; + + @QueryIgnore + public boolean getNewServer() { + return newServer; + } + + @QueryIgnore + public void setNewServer(boolean newServer) { + this.newServer = newServer; + } + } diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java index 6e9cecc63..b9c2c963c 100644 --- a/src/main/java/org/traccar/storage/query/Request.java +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -33,11 +33,11 @@ public class Request { this(columns, condition, null); } - public Request(Columns columns, Condition condition, Order order) { - this(columns, condition, order, null); + public Request(Columns columns, Order order) { + this(columns, null, order); } - public Request(Columns columns, Condition condition, Order order, Limit limit) { + public Request(Columns columns, Condition condition, Order order) { this.columns = columns; this.condition = condition; this.order = order; -- cgit v1.2.3 From 85501f9cf4918d5eee345f83aed7a31eecb26b8d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 16 Jan 2023 07:01:42 -0800 Subject: Fix temperature index --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index bf8ceaf8a..343141dca 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -536,7 +536,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x2F: case 0x30: case 0x31: - position.set(Position.PREFIX_TEMP + buf.readUnsignedByte(), buf.readShortLE() * 0.01); + buf.readUnsignedByte(); // label + position.set(Position.PREFIX_TEMP + (id - 0x2A), buf.readShortLE() * 0.01); break; case 0xFE31: buf.readUnsignedByte(); // alarm protocol -- cgit v1.2.3 From 9ff9bd75fff98cc46395bfa870ba0c1f7ab34d87 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 17 Jan 2023 19:35:26 -0800 Subject: Other JM-LL301 messages --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 5 +++-- .../java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index ef09677bf..5b639ddfc 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -99,7 +99,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LBS_2 = 0xA1; // GK310 public static final int MSG_WIFI_3 = 0xA2; // GK310 public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 - public static final int MSG_FENCE_MULTI = 0xA4; // GK310 + public static final int MSG_FENCE_MULTI = 0xA4; // GK310 & JM-LL301 public static final int MSG_LBS_ALARM = 0xA5; // GK310 & JM-LL301 public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 public static final int MSG_OBD = 0x8C; // FM08ABC @@ -209,6 +209,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: + case MSG_FENCE_MULTI: case MSG_LBS_ALARM: return true; default: @@ -804,7 +805,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type) && buf.readableBytes() > 6) { - decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM); + decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM && type != MSG_LBS_STATUS); } if (hasStatus(type)) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 23c29b0d3..697908a4c 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,18 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78781219012ed042cc00954d00040419000056fe290d0a"), + Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + + verifyAttribute(decoder, binary( + "78782DA4150817073B10CF032EEA9C0B6CE0800015141001CC0100009A00000000000A6F24014605041900FF01908A640D0A"), + Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + + verifyAttribute(decoder, binary( + "78782627100419092D07C5027AC91C0C4658000005370900000000000000008002001900FF00004DF60D0A"), + Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + verifyPosition(decoder, binary( "78781511170103100e1f9904efe30400a97f88003410ffdd000d0a")); -- cgit v1.2.3 From 9a664ae1fc6b564a5b6ddf4923ab3fd54fa23aa3 Mon Sep 17 00:00:00 2001 From: casswarry0 Date: Wed, 18 Jan 2023 16:12:40 -0700 Subject: Removed comments for pull request --- src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 941b10fef..cb0e10042 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -270,17 +270,17 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { int status = buf.readUnsignedShort(); position.setValid(BitUtil.check(status, 0)); - if (BitUtil.check(status, 1)) { // designed for car + if (BitUtil.check(status, 1)) { position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); } - if (BitUtil.check(status, 3)) { // accelerometer supported + if (BitUtil.check(status, 3)) { position.set(Position.KEY_ARMED, BitUtil.check(status, 4)); position.set(Position.KEY_MOTION, BitUtil.check(status, 9)); } - if (BitUtil.check(status, 5)) { // relay control supported + if (BitUtil.check(status, 5)) { position.set(Position.KEY_BLOCKED, BitUtil.check(status, 6)); } - if (BitUtil.check(status, 7)) { // external charging supported + if (BitUtil.check(status, 7)) { position.set(Position.KEY_CHARGE, BitUtil.check(status, 8)); } position.set(Position.KEY_GPS, BitUtil.check(status, 10)); -- cgit v1.2.3 From d2237d91de4dd655a38e9078708eec38906470e0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 19 Jan 2023 13:18:00 -0800 Subject: LDAP doc link --- src/main/java/org/traccar/config/Keys.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 09662fc85..26e922c12 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -510,7 +510,7 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * LDAP server URL. + * LDAP server URL. For more info check LDAP config. */ public static final ConfigKey LDAP_URL = new StringConfigKey( "ldap.url", -- cgit v1.2.3 From 080c289a8a29244bd46cf029eefabbe426ddd00b Mon Sep 17 00:00:00 2001 From: Leo Sadovsky Date: Fri, 20 Jan 2023 14:29:41 +0300 Subject: Added the config parameter `logger.rotate.interval = ['day', 'hour']` that regulates the rotation frequency. The default value is 'day' for backwards compatibility --- setup/default.xml | 1 + src/main/java/org/traccar/config/Keys.java | 11 +++++++++++ src/main/java/org/traccar/helper/Log.java | 20 +++++++++++++------- 3 files changed, 25 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/setup/default.xml b/setup/default.xml index c00d29384..f2ca45fc3 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -24,6 +24,7 @@ info ./logs/tracker-server.log true + day true 86400 diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 26e922c12..19e4540ee 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1574,6 +1574,17 @@ public final class Keys { "logger.rotate", List.of(KeyType.CONFIG)); + /** + * Log file rotation interval, the default rotation interval is once a day. + * This option is ignored if 'logger.rotate' = false + * Available options: day, hour + */ + public static final ConfigKey LOGGER_ROTATE_INTERVAL = new StringConfigKey( + "logger.rotate.interval", + List.of(KeyType.CONFIG), + "day"); + + /** * A list of position attributes to log. */ diff --git a/src/main/java/org/traccar/helper/Log.java b/src/main/java/org/traccar/helper/Log.java index e1b201f9f..a8bf66827 100644 --- a/src/main/java/org/traccar/helper/Log.java +++ b/src/main/java/org/traccar/helper/Log.java @@ -56,18 +56,22 @@ public final class Log { private Writer writer; private final boolean rotate; - RollingFileHandler(String name, boolean rotate) { + private final String logFileSuffix; + + RollingFileHandler(String name, boolean rotate, String rotateInterval) { this.name = name; this.rotate = rotate; + this.logFileSuffix = rotateInterval.equalsIgnoreCase("HOUR") ? "yyyyMMddHH" : "yyyyMMdd"; } + @Override public synchronized void publish(LogRecord record) { if (isLoggable(record)) { try { String suffix = ""; if (rotate) { - suffix = new SimpleDateFormat("yyyyMMdd").format(new Date(record.getMillis())); + suffix = new SimpleDateFormat(this.logFileSuffix).format(new Date(record.getMillis())); if (writer != null && !suffix.equals(this.suffix)) { writer.close(); writer = null; @@ -169,7 +173,7 @@ public final class Log { public static void setupDefaultLogger() { String path = null; - URL url = ClassLoader.getSystemClassLoader().getResource("."); + URL url = ClassLoader.getSystemClassLoader().getResource("."); if (url != null) { File jarPath = new File(url.getPath()); File logsPath = new File(jarPath, "logs"); @@ -178,7 +182,7 @@ public final class Log { } path = new File(logsPath, "tracker-server.log").getPath(); } - setupLogger(path == null, path, Level.WARNING.getName(), false, true); + setupLogger(path == null, path, Level.WARNING.getName(), false, true, "DAY"); } public static void setupLogger(Config config) { @@ -187,11 +191,13 @@ public final class Log { config.getString(Keys.LOGGER_FILE), config.getString(Keys.LOGGER_LEVEL), config.getBoolean(Keys.LOGGER_FULL_STACK_TRACES), - config.getBoolean(Keys.LOGGER_ROTATE)); + config.getBoolean(Keys.LOGGER_ROTATE), + config.getString(Keys.LOGGER_ROTATE_INTERVAL)); } private static void setupLogger( - boolean console, String file, String levelString, boolean fullStackTraces, boolean rotate) { + boolean console, String file, String levelString, + boolean fullStackTraces, boolean rotate, String rotateInterval) { Logger rootLogger = Logger.getLogger(""); for (Handler handler : rootLogger.getHandlers()) { @@ -202,7 +208,7 @@ public final class Log { if (console) { handler = new ConsoleHandler(); } else { - handler = new RollingFileHandler(file, rotate); + handler = new RollingFileHandler(file, rotate, rotateInterval); } handler.setFormatter(new LogFormatter(fullStackTraces)); -- cgit v1.2.3 From f8b0bb61df4865b2bac1f0fe98988c8db207422f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 20 Jan 2023 17:30:13 -0800 Subject: Extend GalileoSky support --- .../traccar/protocol/GalileoProtocolDecoder.java | 48 +++++++++++++++++++++- .../protocol/GalileoProtocolDecoderTest.java | 3 ++ 2 files changed, 49 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index fc8a49cf5..b5c6f77ef 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -23,6 +23,7 @@ import org.traccar.BaseProtocolDecoder; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitBuffer; +import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import org.traccar.session.DeviceSession; @@ -66,7 +67,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { }; int[] l3 = { 0x63, 0x64, 0x6f, 0x5d, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0xfa }; int[] l4 = { 0x20, 0x33, 0x44, 0x90, 0xc0, 0xc2, 0xc3, 0xd3, @@ -88,6 +89,8 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } TAG_LENGTH_MAP.put(0x5b, 7); // variable length TAG_LENGTH_MAP.put(0x5c, 68); + TAG_LENGTH_MAP.put(0xfd, 8); + TAG_LENGTH_MAP.put(0xfe, 8); } private static int getTagLength(int tag) { @@ -239,6 +242,8 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } } else if (header == 0x07) { return decodePhoto(channel, remoteAddress, buf); + } else if (header == 0x08) { + return decodeCompressedPositions(channel, remoteAddress, buf); } return null; @@ -259,7 +264,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { position.setValid(bits.readUnsigned(1) == 0); position.setLongitude(360 * bits.readUnsigned(22) / 4194304.0 - 180); - position.setLatitude(360 * bits.readUnsigned(21) / 2097152.0 - 90); + position.setLatitude(180 * bits.readUnsigned(21) / 2097152.0 - 90); if (bits.readUnsigned(1) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } @@ -392,4 +397,43 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return position; } + private List decodeCompressedPositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + buf.readUnsignedShortLE(); // length + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + List positions = new LinkedList<>(); + while (buf.readableBytes() > 2) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeMinimalDataSet(position, buf); + + int[] tags = new int[BitUtil.to(buf.readUnsignedByte(), 8)]; + for (int i = 0; i < tags.length; i++) { + tags[i] = buf.readUnsignedByte(); + } + + for (int tag : tags) { + decodeTag(position, buf, tag); + } + + positions.add(position); + + } + + sendResponse(channel, 0x02, buf.readUnsignedShortLE()); + + for (Position p : positions) { + p.setDeviceId(deviceSession.getDeviceId()); + } + + return positions.isEmpty() ? null : positions; + } + } diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index f676b1cc1..8c08fee14 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new GalileoProtocolDecoder(null)); + verifyNotNull(decoder, binary( + "01004e01001c0747ea59333030323334303639363034353930000012000063c85e6903000b0321a8f846aba50000000202001e205f5ec863300c4643fdfdbbe6c8fb330000000034e7013505d400000000")); + verifyNotNull(decoder, binary( "01006501001c05cf1f8133303032333430363939303130313000004a000062d8f3ee03000b000f85402088970000000602003503333030323334303639393031303130100000207af3d862300cbe08ee00acfaf001330000760634b301350840090a416b2f42920e")); -- cgit v1.2.3 From 0ec73ae585b66a455f7e43ef6d60f41cde6cf960 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 Jan 2023 09:58:15 -0800 Subject: Commands for readonly users --- src/main/java/org/traccar/api/resource/CommandResource.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 6ef6ee9c5..3460cf6e0 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -105,7 +105,6 @@ public class CommandResource extends ExtendedObjectResource { @POST @Path("send") public Response send(Command entity) throws Exception { - permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); if (entity.getId() > 0) { permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); long deviceId = entity.getDeviceId(); -- cgit v1.2.3 From b77131f4be38295cb643e343613597a6d1ec6562 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 23 Jan 2023 09:16:10 -0800 Subject: GoSafe G6W alarms and temperature --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 7 +++++-- src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 142d1b64f..6fb626d1d 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -263,7 +263,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); if (type.startsWith("AL")) { - if (position != null) { + if (position != null && !position.hasAttribute(Position.KEY_ALARM)) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } sendResponse(channel, id, index, "AL"); @@ -279,6 +279,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { || type.equalsIgnoreCase("HEART") || type.equalsIgnoreCase("BLOOD") || type.equalsIgnoreCase("BPHRT") + || type.equalsIgnoreCase("TEMP") || type.equalsIgnoreCase("btemp2")) { if (buf.isReadable()) { @@ -291,7 +292,9 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { String[] values = buf.toString(StandardCharsets.US_ASCII).split(","); int valueIndex = 0; - if (type.equalsIgnoreCase("btemp2")) { + if (type.equalsIgnoreCase("TEMP")) { + position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(values[valueIndex])); + } else if (type.equalsIgnoreCase("btemp2")) { if (Integer.parseInt(values[valueIndex++]) > 0) { position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(values[valueIndex])); } diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 7eb167a74..0ffe81976 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -17,6 +17,14 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = inject(new WatchProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "[ZJ*5678901234*0001*0009*TEMP,36.5]"), + Position.PREFIX_TEMP + 1, 36.5); + + verifyAttribute(decoder, buffer( + "[ZJ*689466020014198*0003*0113*AL,221121,085515,V,00.000000,N,000.000000,E,0,0,0,0,0,44,0,0,00100000,1,255,460,0,16399,234887445,0,6,WIFI00,68:77:24:1b:e7:a7,-59,WIFI01,68:77:24:1b:e3:30,-75,WIFI02,68:77:24:1b:e3:27,-75,WIFI03,00:41:d2:c0:f2:f1,-76,WIFI04,00:41:d2:c0:f2:f0,-77,WIFI05,68:77:24:1b:e3:d8,-82]"), + Position.KEY_ALARM, Position.ALARM_REMOVING); + verifyNull(decoder, binary( "5b5a4a2a3738393436383035303034323639322a303033342a303433392a4a58544b2c302c77617463685f375f32303232303532363039333935342c312c362c2321414d520a0c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c389814ffcd762fe49d50ae7a2e0cb528aefbf76911df05c2fbe17d050c2200cff77ef0df4d9b4ab9a4340c449814dbe7c63fa82bc3750d800cc48abbffddb0df8e8fda95e5980c49982ff6cf65f9377d02a39c3aaa0c389805f2ff42c1b80e0a0eb1dc0c2998e9defe15cfa3bdbe80d3540c7298c2f6d9239e3eae3c4a81660c490034dbfd513fedad0c2fc3900cc40039b7f71bb0657ba75558c40cd7813b97ff7219777ec7f401260c7d040003bff6f75fdb898a6ba1140cecd127f7f83357cb73a68a5f680cb081d4f6e749e6af8ed367bc480cec1815dfffd2dbed358112af320ccc21179fffbd17a3a61c133b380c920047defc72a784770ec0fe400c383c42f6faebe76fa736e9d1be0c4918e7decddc67ec9afd87ff220cc418e6bffe6cf6c9ac1f83c3900ca6cad1ffe3da24e1be3b547d03c00c6b00b8fee77f60a76d3e7d0292e20c2918b7bfff76387b793d3a36300c7d0400b7fff7f63ae513ac6f74de0c980016fbff7d01f9b30fca67c7220caa982ff6dbd7bf3d8dfed143ec0c44982fdfcb7b517e26f6ea52420c0ed19cfedb438f179d3fc50ec40c008ad2ffff635fe28dc1ec1f860c76cb7d05bffda53eaebe4d201ae20ccccaffbbfd3db4abb6ddf39d0e0c6b00acfeff406fe4a12661caf80c76982fbffffeb17b2f65472f300c7d04c24bf6ef1b10e47f73fc10b40c76036cfecd4e7837145a6a8e900ccccaf2beeba36fbaa36feb60640c7d0400dfffff73bfa3b87d0256a1700c7d04e4efd6efc23b651eb73e77780ccc1813ffffb39f6baa6f3195080c00007afffee0b9df6346ca08d00c6bca7d04feff4d64a7b56f9855da0c769819fbfd954ea5bd7d040ba6420c4c4c09bfffd5f6c57d01930e7d01220cc48a22dffe30bfcbaf08a795140c7d040433b7ff3cba5f3e336a40060cecbd2bfaf775bea7bde7e095ee0cc4caaef7fb623feeaab69eabc20c8c0021bffd1ea4a1b090175a920c7d046445fbdfc1abe910b0ca56160c7d0440cbd7ef03893c7f7d02e1a8c20c85e42dff5fdaa145759d326b5a0ccc4084f75f8eeb7b15e4eb4ff80c6bc22ef7d7eaf8df3b8ff678cc0cca4026f3cf7518fd731ceca3560cec041ffbe7655eaf822f04c4fe0c7d0478e3fbfcb5dfc8a81fdbb9e20cc418e6d7ff777f26affe37cc020cd7977cbff7d0aecb9727be6a0c0c00bde1f2d797fc8754ed09d4ae0cc498279f7e729fcb9eff70c1a60c7d0478e5bfffc67eef953fda69aa0c7200f1bbf7e891ef5a287cb5b80c983629fee5555f739f8a29279a0c76d103bef73f55a6bf89ba8ce40cc46424f6ded9a194167a067d05880cc4780efeffc37fae944d89bfb40c4464bffffb6dd54e8344394a5c0c49781ffffc653feaa31af59ac00cc464cebfd76ae4e8a55d5b5a4a2a3738393436383035303034323639322a303033352a303434332a4a58544b2c302c77617463685f375f32303232303532363039333935342c322c362c5f24fbbc0c7d04983effcfe35fbd8fff7ce6f60c448a1dfbd715bec3b42448e58a0c0e0421bf5f17ebc31a43301bc40c768ababf4f66cf629ee31fe9900c6b6426bf5f4eb7669dacc439140c945733bff9351e7d04ab6be54ef60ccc98bfbffbf67f63b78d8f42880c7d0400c6f7fffab5cbae8e8275da0c0097ffdefff5dfafb0c4727d04980ccc78d1f6ff1a6b7e37631059fa0c760045f3fd853fea877d03aa87440cc40022f7ffa8b5c58f6e80c58e0ccc4c1f9ffff32fa7af87de04560cb09801f6fdd32efcbdad9495b60c6b987d05bff72d61eb687d05a9f9e20cca57c7ffff6cb1fe3387ea596e0c629823dedfbfc50b97965e44ea0c4918ccbfd7cc75e59fff92e9ee0c8c78e7faff707ffda60ec3ada60c30c217befffcb8f3290f06d75e0c0e8a7bb7dff3eec7b7928ef6680c38ca1cdeff272ba012597d051a520c0018dfffeff27d01e369b3bcd7d80c98146eb2fc7f45c38e1ce53e120c3d5700ff7fd44bee28aa089d900c007157bffffe30302d7d0583585c0ccc5747bfe7f73cff7d02de1098240c7d047865f6feca71d70bdfaab6a20cecb946bfd966be74b61a06c6660c441612ffe7eb966a8c2886cf760ccc7827bffd653ff7980a62e9320c00ca98f7fc1b311a3986700cc20c490017bfff70cfe7bb455637320c6228afbf7e6da4c59763b693740cccc2b5fee1951975760e4a9dca0c0000faffdb255f6f86af4be6fc0cccc2ffdfff7d0225efbc847c42760cb48a8fdffbe23ff1a78782cbe60c7d04980cffff6e6dfc75a6c65a500ce62808bfff24f853748a9537400cb4004ebfeb6e70aa4314903e8c0cb46408ff72d62f44945f64897d040cccca7abfff2db5c6bfcc345e700c7d04c24dd6fd5f95638f78974a800cc4caffffffb17d01c36bdd7d047c2e0c7d0436d1f7f8917f83af7fc5c2180c070449f6fe570f128577c8c97d040c7d047813f6df3fd17d026b6790d1b80cc400c9d6d92dc56497843ed10a0c44986effffe13fef8eef7c717a0c7d049872bbfdad3abe2be0d60b240c4900adbf7d02dfa4ef960fdf23580c629845fefc5a650fbf8b0d4cda0c7d040076b7ef273fe78fce983ae40c4a00ded7ff629f7fab4531501c0c6200b7ffedf13fe6a68f01fb6c0cc49809f77fdb91517fb39e8ba00c760009bf7fd6afe7b46921f27a0cecbd1df6faf99120776e807d03fe0c98ca23fbff3749fb5ed3909c160cc44cbbbfffbd70e77d0367bc2e740c499816f77fe2ffe08edd7d048c9e0c940021beff1df0f1338c2f1a3a0c7d040083feebba1c756e5760c2200c94981dfffdf921b92b99909ba40c7d04984ebbdf7ff0c77d025a1fbfc00c7657b3ff77f4befcae2bf625640c62ca53f7fdb35f2e92af3bd5c60c7d049878bbdfc0dfc1bdaa1918000cc404bbbfefb41ee6b50a39bf180c767874f7fb8ee156320ee600020c69981cffffe0fff6bb2764acaa0cec781bfbff7d0324eb9b4b4d5d5b5a4a2a3738393436383035303034323639322a303033362a303433302a4a58544b2c302c77617463685f375f32303232303532363039333935342c332c362c73580c07ca4fbbfff5bec5abcfac465c0c0042a8beff316aed38fe4603dc0c7d04577d04fefdc929f7294ce7520c0c76984dfaff402fe68ebe113b000c7d0436a6fed465ff4f8d8e3306300c44e434f7f79e84abb8fa081be80c983636bef7e128bf7d03d34c71c80cd7982dffd54cac94536beab1320c058bd6bfff701fe69d1a39d1e80c76caedb77ffea0e47febb469440c0098b2bef5e55eed981672b1c40cd800d1bef4bda58daf7d01d309180c08cadffbfc31799f5613fab2da0c7d049828beffa5eea0bd09a14c2e0c0000e59feb5f9dff7f4945e98e0cc40046ffcfe57fb58f7d053dd9e20c7d040047d7ffd38f67aa9db8d38c0c7698d2df5fe2efc6bb0f5a18220c980367bbfd95dae73e3bf2b59a0c49813796fdf5efab9d3ed7d3d80c9800ebd7fdb831ae8f91811e920c7d04ca74bbff5cdcf45605c25f140c013e029fbfe7ffc299376b409a0c7510009e7d02010f68824cccead60cb13b00f7d5821e6c8d594a06880c75ec00f6e782e8f06b0c610d1a0cc09843dfef117fa5b3aef236f40cdcc208ffff4831f83703ca20c00cc09800bf7fd71eec9ba34e3c200c650f6bffd5bc4dbe7ec5b0f1d80c0d1c1f92ef917fa0b96023eac00c8efb1db6bfa42eed9f69051d4e0c8eff23b2fe4486d56ef44f702e0c8ebc1b9657d46eeea852ac337e0c8efb1f96d9877fc9b34c38f1540c121c2796df13577c727f8cedec0ca9107d05afdd6a9d957ab76c02560c121c2dd6bfd33fa5b844f27d02340cb11037b6e3962e6eaf52d6e7460c2b1c3db2dfe61eef9aad3dcc0a0c542e42d763e709fe723a83ae7c0c7cfa56bf7fedb8763c3f8ab2c00ca40022efff2411604d22a485e00c228adcbfdfcd748293c66b0bf20cb10f0097ff806dcf7a0a640d6e0c5a0400b7e3030ef4ae0a6046f80cb82812fe7b04d77e4bab11894a0c541c24b2dd53fea5891e3824420ca9fb26b2d7156fa485049cac420ca91c2d9edb2487526c2e2260fa0ca9bc25b65ff28e41a34232c0f00c8efb25b649e51ec39c0ae6703a0c70f425a6c820dfaf2f8124c8960c80f42794b323aed9ca9b6924be0cb93b278e3e8d929c36bb70b6360c587b27524f85857d056d214841660cda2f278b4c876eb3186e5acc540ce6832f6e3f0d82f81226e6dc3a0c0b922feff50a03d03c98ae28360c03d62befb54ab611de0c8addee0c84d626b7fdb4461556dc0153040c0b0f27ff5781c5c2b32f6762140c49bf2dfaf521969b702ecb11d80c7d050f27cfed75bfab95dc4af3180c011c3d8e7451df80a5cd0948080c7c2e35f2c7b0becca22e50769e0c7c1c3d965e628f46a9a58ae6100c7c2e3b965f4a6b5ebd1436b0b00c7c863eaedf18c7816cdeeed7e20c2b3e3df6b73952b2b1abc048a00c7cfb3db6cd67ae68cda18af9d60c2bff3e96df12ff61b39627cd580c7c863fd6cd810ee595d85ee6645d5b5a4a2a3738393436383035303034323639322a303033372a303433372a4a58544b2c302c77617463685f375f32303232303532363039333935342c342c362c0c7cff3fb65f812fe196dc62d8360c7c2e3db2de738fae9ca7c7236c0c2b2e3d96df6c1d775a3df5a47e0c7c3e3f96fe943dc07e81e170700c75503fb7d6a6197f1b08df85440c5a133ab6d6a0e68f3acb04b7b00cfa293fd6cfc20c390d5265d3c80c581347b278077d03dc22d9e49c680ce64d47924e8dcdffe9be19dc100cb90f4f9e612d2201961c2e111c0c003b4febb58a96c809ab5a71040ce6d759fbddba54b2aa9d9d983e0cc029576ecf1f703099d84994520c4029579e7d0281577073f5629dd80c5a2952b6fed177177d01e57d0175c20cd8647d044f7e3c58aba523ddb0720cb56753d3e9c6799f95938401f60c756414ff5f00fb57bc4d7e111c0c7c085573ef743ee19ca30057e00c752e5ab77e34eec69f3cbe53940c542e4d96d6e7ff03854a9506620c7cff55b6efca197610a86606180c7cfb55b67eb25f4b999c002bf20c7c107d03beeb451fad8d042492740cb8f05eb5ff664f679c1cc991c60ce1671bffd33d9445b57d0584c7d60c07781dfef5e3ee81b45ff8a8c80cc40072b7dfe6fe6e978257253a0cb1131fe6783035868e439b00d80c583b27b17ecb53dd165c3422180c703b2fbeb18d023e14d90304700c3cce2b93cdc2e6b3550a5546160cb13b3b72fe24273859059b52040c224d34edc742f6bb7c877d02b5940cb84d37cdcfcbc3f03a041cf4ac0ca4923a9f3b74e805b235cce8660c759000fbfd90565072aa7d03bb520cb592017f411dcbe80a0cc420360c09d6528fcf2e25b382ee46d75a0ce2e853d3cfb617fd7d023f05e0780c07cc3bbabfa9f6cec5aa48ac600c404208fb678a4cf16a9c09098c0cf14244fbdfc2afe7932fe57d02900c011c369e7d0264a8570a54f9a2e80cb1103daed6249fe59dc888c2ac0cb1103573c5f697be759923ecc80c705f7d059effaaa4b09b976f375a0c804223bbed89767d041693edab180cb49819d7eb5a8573bb10c951540c3c643af74f021f25b6dd3b7d02040c07982bd73fb31fe38f09a227a40c037610ff7d03c6058098fef936a80c03b808debbe055a1a71319128c0c6b8f2e9e3bb52d71c226d3141a0cdab82d7fa9d416167a1cb950020c03c32bb23ee9e3743f3b6853060cc02937adb5157d05f4a6960c1b680c4076365e6b754bda9394a7aa720c06293ef23313fb1b94bcc2c09a0ce676006bbd8e0417941b90d23c0cb9294f7d01fd3d65748cf6d1cc220c03767d035e3a65e6f2514ab1db060ce6d965bf4035f65c79a9e4446a0ce62921dbf46457b56cd65f6c500c584d6bba7ea8166edd6cf7693a0cb939227bfca25f82a7c4202f2e0c06ce2b9a4f0d95f39eb43c22840c06901eef6fd15fe48f452000e00c62023afbffb269beba0ee0ac540ce6ec00f37b8139f2026e80f1440c22501dfe7d017d03ed8c3ff6803f240cc48ae3b7fd725e63a347cd64100c0094f8efdeb0a9f35c83eb06b00c005d5b5a4a2a3738393436383035303034323639322a303033382a303433332a4a58544b2c302c77617463685f375f32303232303532363039333935342c352c362c6647deef2df57fb68fd76b660c44e43cbfefc0beec867d025c3f920cb4507d01ff6f42ee6c1f58a0db0e0c7d045701ff7f19f9f90fdff037c20c4404259efcd47d02a52b7ef6df0e0c7d04d128f3578db14779993109560ce1e41ecffd2851af49256b1ecc0c7d049837ffff707168db3dd1ac240cc09419f7f39a7d013d6ec1b4e55c0cc4881cff5f49f55fadc52285a40c06ce9ad7dbb8349b97031ac3b00c407d049d9bed74dfadad950eab560c06799ffac7a924b18bdf11c3d40c8054a2f777522e65be921a77240c8042a19bff706fe5b7e3e7d0360cd82840bff3f4fe429bea0081560c0064419fd9157f8b9c797e92c20cc47fe2b7d5e6ee45bf0524010e0c0894299e7d037e4553bcbbc0989e0c40501bbbdc926f8daf53885e0a0c80971ffee559f5bf98ed54cf140c00581abbffac75b88b14d5e3780c5a046dd66fd7bfe5b7ca749df40c403672bbcfe47ee797860ded5e0cb5502efb7ee2ffc7bbdc27d0880c44ca08fbf7031ecd9321d21ef40cdc9806fefde36f0699ad1569420c22cb1bfbdc974fcb900ab601440c00cb1cfbdfd2f7d2730b0b46680c0b4203dfef309fe0adc121e2080c225829feeb901f25b926343bae0c624204dfff4875b69ceda4df4c0c499886ffe7301e8e8bf9ef0a260cdce408dbef829fe45337e98d860c010800ef76088d8015f3b2c84e0c755c3ecfc898f50fbcdb9344220c7c7d03459349337d01e4949da1b4ec0c7cf046ae6e4a90df3552070a5e0c7cf045d23fbba0951147986eca0c7536426e6ef2ef0b7d01c22fd2960cb8284e9db92d40552988334f200cb8024acdbfea90d13b545fe35e0cb8f04d5e48659d48b97c1096140c7c084f79df4402702126bf358a0cb8a74d4def66535e145638d12e0c543e4d8edfa2531b15a340eb800cb83e4eafbd9031291a8563e4780c54a74ef1c7300da79aa94bb67d050cb8f04eba6fb0325813871511b80ce20ff6fffd404ed58ecf264c8e0c7c0f1cb3fe1a36fb7187c379d00c7c3e52f6727d0261ca8bdd1361b80cb8d64d9a4fb1cfe0aadaaa7d05c40c2b2e44b2bfb9b4dcad9d7d0200280c7c3b47d5db803fc2aee71a77f00c7c1343b2bfa06ee6ad3228f10a0c7c3b4a76477fe7650b0c809ca80c54d74b92dbc327134514d6126e0c7c5f4a8f4f74efaaa5cd0a43bc0c7c104bb64ff5ce604fa2028b680c7cff4aaec7f7a9394cc4c599e60cb8ce52eeb553d215a6a466b4120c750f4fae5f9816c04a0a3f751e0c75e04f73c58e96bb4b925a4c680cb80f4b6e3fe1635614bbdeccbc0c7c3b4faf7e825e42d473ee76800ce298578ffcb61f0af936387bbe0cb800e39bf62410681583e0d2b20cb4987d05ff7f297bf69eaf4cd8b40cb57815bf7f300fcffe9fae966a0cb497acd75fd37f648d00d141a00cc48af9fffe1a3b979b8f8573e80c29bff1bf4b94c6fd7c3eec075e0c7cce1f5d5b5a4a2a3738393436383035303034323639322a303033392a303065352a4a58544b2c302c77617463685f375f32303232303532363039333935342c362c362c8f5cf9f34fa6edceb18c0ca4ce436e7d02d329de94b63eb11a0cb894438f44cf753dbc1a83b4560cb8e44391eff729d4155a231bf40cb59443f373b4288492cd6e38160c5a42049bfec8678ad42bce0c560cb12e39fec3d1fe24b5572ee0be0cb1ce35fe33688455aa74e3ffa40cb1d635df4b704160ae864a7d03440cb10f3267dbf4a21d540ca1051c0cb11337724f8747f5547d054e91660cb1a73692df964f3bbb0758d41a0cfe05b60c314460297eae4185f20cad673ceb6dfa05ddbe0278d5de5d")); -- cgit v1.2.3 From 4722f9b6b6489ea7e9dea0c01ae1d7d3044310b5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 23 Jan 2023 16:34:40 -0800 Subject: Update Iridium decoding --- .../traccar/protocol/GalileoProtocolDecoder.java | 23 ++++++++++++++-------- .../protocol/GalileoProtocolDecoderTest.java | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index b5c6f77ef..d4bd45c4f 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -272,10 +272,10 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { private Position decodeIridiumPosition(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - buf.readUnsignedShortLE(); // length + buf.readUnsignedShort(); // length buf.skipBytes(3); // identification header - buf.readUnsignedIntLE(); // index + buf.readUnsignedInt(); // index DeviceSession deviceSession = getDeviceSession( channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); @@ -288,12 +288,19 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // session status buf.skipBytes(4); // reserved - buf.readUnsignedIntLE(); // date and time - - buf.skipBytes(23); // coordinates block - - buf.skipBytes(3); // data tag header - decodeMinimalDataSet(position, buf); + position.setTime(new Date(buf.readUnsignedInt() * 1000)); + + buf.skipBytes(3); // coordinates header + int flags = buf.readUnsignedByte(); + double latitude = buf.readUnsignedByte() + buf.readUnsignedShort() / 60000.0; + double longitude = buf.readUnsignedByte() + buf.readUnsignedShort() / 60000.0; + position.setLatitude(BitUtil.check(flags, 1) ? -latitude : latitude); + position.setLongitude(BitUtil.check(flags, 0) ? -longitude : longitude); + buf.readUnsignedInt(); // accuracy + + buf.readUnsignedByte(); // data tag header + // ByteBuf data = buf.readSlice(buf.readUnsignedShort()); + // decodeMinimalDataSet(position, data); return position; } diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index 8c08fee14..df7f37903 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new GalileoProtocolDecoder(null)); - verifyNotNull(decoder, binary( + verifyPosition(decoder, binary( "01004e01001c0747ea59333030323334303639363034353930000012000063c85e6903000b0321a8f846aba50000000202001e205f5ec863300c4643fdfdbbe6c8fb330000000034e7013505d400000000")); verifyNotNull(decoder, binary( -- cgit v1.2.3 From 3771dd156efb068b2f6ba586ec5b951985c40cc5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Jan 2023 09:27:14 -0800 Subject: Handle new watch format --- .../org/traccar/protocol/WatchProtocolDecoder.java | 60 ++++++++++++---------- .../traccar/protocol/WatchProtocolDecoderTest.java | 3 ++ 2 files changed, 35 insertions(+), 28 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 6fb626d1d..e100d0dc0 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -139,41 +139,45 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { String[] values = parser.next().split(","); int index = 0; - Network network = new Network(); - - int cellCount = Integer.parseInt(values[index++]); - if (cellCount > 0) { - index += 1; // timing advance - int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - - for (int i = 0; i < cellCount; i++) { - int lac = Integer.parseInt(values[index++]); - int cid = Integer.parseInt(values[index++]); - String rssi = values[index++]; - if (!rssi.isEmpty()) { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); - } else { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + if (values.length < 4 || !values[index + 3].startsWith("F")) { + + Network network = new Network(); + + int cellCount = Integer.parseInt(values[index++]); + if (cellCount > 0) { + index += 1; // timing advance + int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + + for (int i = 0; i < cellCount; i++) { + int lac = Integer.parseInt(values[index++]); + int cid = Integer.parseInt(values[index++]); + String rssi = values[index++]; + if (!rssi.isEmpty()) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); + } else { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + } } } - } - if (index < values.length && !values[index].isEmpty()) { - int wifiCount = Integer.parseInt(values[index++]); + if (index < values.length && !values[index].isEmpty()) { + int wifiCount = Integer.parseInt(values[index++]); - for (int i = 0; i < wifiCount; i++) { - index += 1; // wifi name - String macAddress = values[index++]; - String rssi = values[index++]; - if (!macAddress.isEmpty() && !macAddress.equals("0") && !rssi.isEmpty()) { - network.addWifiAccessPoint(WifiAccessPoint.from(macAddress, Integer.parseInt(rssi))); + for (int i = 0; i < wifiCount; i++) { + index += 1; // wifi name + String macAddress = values[index++]; + String rssi = values[index++]; + if (!macAddress.isEmpty() && !macAddress.equals("0") && !rssi.isEmpty()) { + network.addWifiAccessPoint(WifiAccessPoint.from(macAddress, Integer.parseInt(rssi))); + } } } - } - if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { - position.setNetwork(network); + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + } return position; diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 0ffe81976..09dd46101 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = inject(new WatchProtocolDecoder(null)); + verifyPosition(decoder, buffer( + "[SG*9059011020*006b*UD2,240123,162011,A,54.427621,N,6.409190,W,0.00,0,0,8,19,88,0,0,00000000,1,1,FFFF,FFFF,FFFE,3B882A2,132,,00]")); + verifyAttribute(decoder, buffer( "[ZJ*5678901234*0001*0009*TEMP,36.5]"), Position.PREFIX_TEMP + 1, 36.5); -- cgit v1.2.3 From 8841cea8676057756f23e1f9a710a5a19ac5e63a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Jan 2023 09:27:14 -0800 Subject: Model for scheduled reports --- schema/changelog-5.6.xml | 57 +++++++++++++++++++++++++ src/main/java/org/traccar/model/Report.java | 65 +++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 src/main/java/org/traccar/model/Report.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.6.xml b/schema/changelog-5.6.xml index 335f7b3a8..d7768f8e2 100644 --- a/schema/changelog-5.6.xml +++ b/schema/changelog-5.6.xml @@ -12,6 +12,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/traccar/model/Report.java b/src/main/java/org/traccar/model/Report.java new file mode 100644 index 000000000..393f6fef7 --- /dev/null +++ b/src/main/java/org/traccar/model/Report.java @@ -0,0 +1,65 @@ +/* + * 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.model; + +import org.traccar.storage.StorageName; + +import java.util.Date; + +@StorageName("tc_reports") +public class Report extends ExtendedModel { + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + private Date from; + + public Date getFrom() { + return from; + } + + public void setFrom(Date from) { + this.from = from; + } + + private Date to; + + public Date getTo() { + return to; + } + + public void setTo(Date to) { + this.to = to; + } + +} -- cgit v1.2.3 From 51c167fa8067ac81a47914211cc252f5dd3e40f1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Jan 2023 09:59:30 -0800 Subject: Add calendar to report --- schema/changelog-5.6.xml | 5 +++++ src/main/java/org/traccar/model/Report.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/schema/changelog-5.6.xml b/schema/changelog-5.6.xml index d7768f8e2..38b206902 100644 --- a/schema/changelog-5.6.xml +++ b/schema/changelog-5.6.xml @@ -22,6 +22,9 @@ + + + @@ -33,6 +36,8 @@ + + diff --git a/src/main/java/org/traccar/model/Report.java b/src/main/java/org/traccar/model/Report.java index 393f6fef7..83bb2e920 100644 --- a/src/main/java/org/traccar/model/Report.java +++ b/src/main/java/org/traccar/model/Report.java @@ -20,7 +20,7 @@ import org.traccar.storage.StorageName; import java.util.Date; @StorageName("tc_reports") -public class Report extends ExtendedModel { +public class Report extends ScheduledModel { private String type; -- cgit v1.2.3 From c49fc3b40a88deb2f7e09cd41a7bc74ee2677636 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Jan 2023 10:25:35 -0800 Subject: Minor lint fix --- src/main/java/org/traccar/helper/ClassScanner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/ClassScanner.java b/src/main/java/org/traccar/helper/ClassScanner.java index c928f6a12..c201d101f 100644 --- a/src/main/java/org/traccar/helper/ClassScanner.java +++ b/src/main/java/org/traccar/helper/ClassScanner.java @@ -46,7 +46,7 @@ public final class ClassScanner { URL packageUrl = baseClass.getClassLoader().getResource(packagePath); if (packageUrl.getProtocol().equals("jar")) { - String jarFileName = URLDecoder.decode(packageUrl.getFile(), StandardCharsets.UTF_8.name()); + String jarFileName = URLDecoder.decode(packageUrl.getFile(), StandardCharsets.UTF_8); try (JarFile jf = new JarFile(jarFileName.substring(5, jarFileName.indexOf("!")))) { Enumeration jarEntries = jf.entries(); while (jarEntries.hasMoreElements()) { -- cgit v1.2.3 From 1c91d35263f1d00c00db44f7b2ff373aacb28478 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Jan 2023 10:30:58 -0800 Subject: Handle new watch format --- src/main/java/org/traccar/helper/StringUtil.java | 32 ++++++++++++++++++++++ .../org/traccar/protocol/WatchProtocolDecoder.java | 9 +++--- .../traccar/protocol/WatchProtocolDecoderTest.java | 3 ++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/traccar/helper/StringUtil.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/StringUtil.java b/src/main/java/org/traccar/helper/StringUtil.java new file mode 100644 index 000000000..9b4d717f4 --- /dev/null +++ b/src/main/java/org/traccar/helper/StringUtil.java @@ -0,0 +1,32 @@ +/* + * 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.helper; + +public final class StringUtil { + + private StringUtil() { + } + + public static boolean containsHex(String value) { + for (char c : value.toCharArray()) { + if (c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') { + return true; + } + } + return false; + } + +} diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index e100d0dc0..40d56b130 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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 io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.StringUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -139,7 +140,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { String[] values = parser.next().split(","); int index = 0; - if (values.length < 4 || !values[index + 3].startsWith("F")) { + if (values.length < 4 || !StringUtil.containsHex(values[index + 3])) { Network network = new Network(); @@ -150,8 +151,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; for (int i = 0; i < cellCount; i++) { - int lac = Integer.parseInt(values[index++]); - int cid = Integer.parseInt(values[index++]); + int lac = Integer.parseInt(values[index], StringUtil.containsHex(values[index++]) ? 16 : 10); + int cid = Integer.parseInt(values[index], StringUtil.containsHex(values[index++]) ? 16 : 10); String rssi = values[index++]; if (!rssi.isEmpty()) { network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 09dd46101..37fab7e40 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = inject(new WatchProtocolDecoder(null)); + verifyPosition(decoder, buffer( + "[SG*9059011020*0067*AL,240123,181628,V,54.427538,N,6.409275,W,0.00,0,0,0,19,90,0,0,00000000,1,1,234,10,55C0,3B882A2,132,,10]")); + verifyPosition(decoder, buffer( "[SG*9059011020*006b*UD2,240123,162011,A,54.427621,N,6.409190,W,0.00,0,0,8,19,88,0,0,00000000,1,1,FFFF,FFFF,FFFE,3B882A2,132,,00]")); -- cgit v1.2.3 From e5a52e47b5fcae268ee89748ffe9bc05ab726c31 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Jan 2023 17:45:35 -0800 Subject: Computed attributes for properties --- .../traccar/handler/ComputedAttributesHandler.java | 46 +++++++++++++++++----- 1 file changed, 37 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index c9f1f63d7..620852502 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 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -116,17 +116,45 @@ public class ComputedAttributesHandler extends BaseDataHandler { } if (result != null) { try { - switch (attribute.getType()) { - case "number": - Number numberValue = (Number) result; - position.getAttributes().put(attribute.getAttribute(), numberValue); + switch (attribute.getAttribute()) { + case "valid": + position.setValid((Boolean) result); break; - case "boolean": - Boolean booleanValue = (Boolean) result; - position.getAttributes().put(attribute.getAttribute(), booleanValue); + case "latitude": + position.setLatitude(((Number) result).doubleValue()); + break; + case "longitude": + position.setLongitude(((Number) result).doubleValue()); + break; + case "altitude": + position.setAltitude(((Number) result).doubleValue()); + break; + case "speed": + position.setSpeed(((Number) result).doubleValue()); + break; + case "course": + position.setCourse(((Number) result).doubleValue()); + break; + case "address": + position.setAddress((String) result); + break; + case "accuracy": + position.setAccuracy(((Number) result).doubleValue()); break; default: - position.getAttributes().put(attribute.getAttribute(), result.toString()); + switch (attribute.getType()) { + case "number": + Number numberValue = (Number) result; + position.getAttributes().put(attribute.getAttribute(), numberValue); + break; + case "boolean": + Boolean booleanValue = (Boolean) result; + position.getAttributes().put(attribute.getAttribute(), booleanValue); + break; + default: + position.getAttributes().put(attribute.getAttribute(), result.toString()); + } + break; } } catch (ClassCastException error) { LOGGER.warn("Attribute cast error", error); -- cgit v1.2.3 From c828e6af3ca96e51c20f5e189ab1293c4fe29c8a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 25 Jan 2023 14:25:40 -0800 Subject: Add scheduled reports task --- .../org/traccar/api/resource/ReportResource.java | 39 +----- .../org/traccar/reports/common/ReportExecutor.java | 25 ++++ .../org/traccar/reports/common/ReportMailer.java | 70 ++++++++++ .../java/org/traccar/schedule/ScheduleManager.java | 10 +- .../java/org/traccar/schedule/TaskReports.java | 154 +++++++++++++++++++++ 5 files changed, 262 insertions(+), 36 deletions(-) create mode 100644 src/main/java/org/traccar/reports/common/ReportExecutor.java create mode 100644 src/main/java/org/traccar/reports/common/ReportMailer.java create mode 100644 src/main/java/org/traccar/schedule/TaskReports.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 70177dd4d..6944de9cb 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,27 +19,23 @@ package org.traccar.api.resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.BaseResource; -import org.traccar.mail.MailManager; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.reports.EventsReportProvider; import org.traccar.reports.RouteReportProvider; import org.traccar.reports.StopsReportProvider; import org.traccar.reports.SummaryReportProvider; import org.traccar.reports.TripsReportProvider; +import org.traccar.reports.common.ReportExecutor; +import org.traccar.reports.common.ReportMailer; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.SummaryReportItem; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.StorageException; -import javax.activation.DataHandler; import javax.inject.Inject; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.util.ByteArrayDataSource; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -51,9 +47,6 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; import java.util.Collection; import java.util.Date; import java.util.List; @@ -83,31 +76,11 @@ public class ReportResource extends BaseResource { private TripsReportProvider tripsReportProvider; @Inject - private MailManager mailManager; + private ReportMailer reportMailer; - private interface ReportExecutor { - void execute(OutputStream stream) throws StorageException, IOException; - } - - private Response executeReport( - long userId, boolean mail, ReportExecutor executor) { + private Response executeReport(long userId, boolean mail, ReportExecutor executor) { if (mail) { - new Thread(() -> { - try { - var stream = new ByteArrayOutputStream(); - executor.execute(stream); - - MimeBodyPart attachment = new MimeBodyPart(); - attachment.setFileName("report.xlsx"); - attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( - stream.toByteArray(), "application/octet-stream"))); - - User user = permissionsService.getUser(userId); - mailManager.sendMessage(user, "Report", "The report is in the attachment.", attachment); - } catch (StorageException | IOException | MessagingException e) { - LOGGER.warn("Report failed", e); - } - }).start(); + reportMailer.sendAsync(userId, executor); return Response.noContent().build(); } else { StreamingOutput stream = output -> { diff --git a/src/main/java/org/traccar/reports/common/ReportExecutor.java b/src/main/java/org/traccar/reports/common/ReportExecutor.java new file mode 100644 index 000000000..aed4b8c23 --- /dev/null +++ b/src/main/java/org/traccar/reports/common/ReportExecutor.java @@ -0,0 +1,25 @@ +/* + * 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.reports.common; + +import org.traccar.storage.StorageException; + +import java.io.IOException; +import java.io.OutputStream; + +public interface ReportExecutor { + void execute(OutputStream stream) throws StorageException, IOException; +} diff --git a/src/main/java/org/traccar/reports/common/ReportMailer.java b/src/main/java/org/traccar/reports/common/ReportMailer.java new file mode 100644 index 000000000..32bbd4b17 --- /dev/null +++ b/src/main/java/org/traccar/reports/common/ReportMailer.java @@ -0,0 +1,70 @@ +/* + * 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.reports.common; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.api.security.PermissionsService; +import org.traccar.mail.MailManager; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.activation.DataHandler; +import javax.inject.Inject; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javax.mail.util.ByteArrayDataSource; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class ReportMailer { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReportMailer.class); + + private final Storage storage; + private final MailManager mailManager; + + @Inject + public ReportMailer(Storage storage, MailManager mailManager) { + this.storage = storage; + this.mailManager = mailManager; + } + + public void sendAsync(long userId, ReportExecutor executor) { + new Thread(() -> { + try { + var stream = new ByteArrayOutputStream(); + executor.execute(stream); + + MimeBodyPart attachment = new MimeBodyPart(); + attachment.setFileName("report.xlsx"); + attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( + stream.toByteArray(), "application/octet-stream"))); + + User user = storage.getObject( + User.class, new Request(new Columns.All(), new Condition.Equals("id", userId))); + mailManager.sendMessage(user, "Report", "The report is in the attachment.", attachment); + } catch (StorageException | IOException | MessagingException e) { + LOGGER.warn("Email report failed", e); + } + }).start(); + } + +} diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 6412a186a..e1de3b3af 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.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. @@ -38,8 +38,12 @@ public class ScheduleManager implements LifecycleObject { @Override public void start() { executor = Executors.newSingleThreadScheduledExecutor(); - List.of(TaskDeviceInactivityCheck.class, TaskWebSocketKeepalive.class, TaskHealthCheck.class) - .forEach(task -> injector.getInstance(task).schedule(executor)); + var tasks = List.of( + TaskReports.class, + TaskDeviceInactivityCheck.class, + TaskWebSocketKeepalive.class, + TaskHealthCheck.class); + tasks.forEach(task -> injector.getInstance(task).schedule(executor)); } @Override diff --git a/src/main/java/org/traccar/schedule/TaskReports.java b/src/main/java/org/traccar/schedule/TaskReports.java new file mode 100644 index 000000000..259eb10d4 --- /dev/null +++ b/src/main/java/org/traccar/schedule/TaskReports.java @@ -0,0 +1,154 @@ +/* + * 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.schedule; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.model.BaseModel; +import org.traccar.model.Calendar; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.Report; +import org.traccar.model.User; +import org.traccar.reports.EventsReportProvider; +import org.traccar.reports.RouteReportProvider; +import org.traccar.reports.StopsReportProvider; +import org.traccar.reports.SummaryReportProvider; +import org.traccar.reports.TripsReportProvider; +import org.traccar.reports.common.ReportMailer; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +public class TaskReports implements ScheduleTask { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskReports.class); + + private static final long CHECK_PERIOD_MINUTES = 1; + + private final Storage storage; + private final ReportMailer reportMailer; + + @Inject + private EventsReportProvider eventsReportProvider; + + @Inject + private RouteReportProvider routeReportProvider; + + @Inject + private StopsReportProvider stopsReportProvider; + + @Inject + private SummaryReportProvider summaryReportProvider; + + @Inject + private TripsReportProvider tripsReportProvider; + + @Inject + public TaskReports(Storage storage, ReportMailer reportMailer) { + this.storage = storage; + this.reportMailer = reportMailer; + } + + @Override + public void schedule(ScheduledExecutorService executor) { + executor.scheduleAtFixedRate(this, CHECK_PERIOD_MINUTES, CHECK_PERIOD_MINUTES, TimeUnit.MINUTES); + } + + @Override + public void run() { + Date currentCheck = new Date(); + Date lastCheck = new Date(System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(CHECK_PERIOD_MINUTES)); + + try { + for (Report report : storage.getObjects(Report.class, new Request(new Columns.All()))) { + Calendar calendar = storage.getObject(Calendar.class, new Request( + new Columns.All(), new Condition.Equals("id", report.getCalendarId()))); + if (calendar.checkMoment(currentCheck) && !calendar.checkMoment(lastCheck)) { + executeReport(report); + } + } + } catch (StorageException e) { + LOGGER.warn("Scheduled reports error", e); + } + } + + private void executeReport(Report report) throws StorageException { + var deviceIds = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), + new Condition.Permission(Device.class, Report.class, report.getId()))) + .stream().map(BaseModel::getId).collect(Collectors.toList()); + var groupIds = storage.getObjects(Group.class, new Request( + new Columns.Include("id"), + new Condition.Permission(Group.class, Report.class, report.getId()))) + .stream().map(BaseModel::getId).collect(Collectors.toList()); + var users = storage.getObjects(User.class, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, Report.class, report.getId()))); + for (User user : users) { + switch (report.getType()) { + case "events": + reportMailer.sendAsync(user.getId(), stream -> { + eventsReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, + List.of(), report.getFrom(), report.getTo()); + }); + break; + case "route": + reportMailer.sendAsync(user.getId(), stream -> { + routeReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, + report.getFrom(), report.getTo()); + }); + break; + case "summary": + reportMailer.sendAsync(user.getId(), stream -> { + summaryReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, + report.getFrom(), report.getTo(), false); + }); + break; + case "trips": + reportMailer.sendAsync(user.getId(), stream -> { + tripsReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, + report.getFrom(), report.getTo()); + }); + break; + case "stops": + reportMailer.sendAsync(user.getId(), stream -> { + stopsReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, + report.getFrom(), report.getTo()); + }); + break; + default: + LOGGER.warn("Unsupported report type {}", report.getType()); + break; + } + } + } + +} -- cgit v1.2.3 From 5d572a11870b16668d2803481a2a687d3625abe0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 25 Jan 2023 14:28:35 -0800 Subject: Remove missing import --- src/main/java/org/traccar/reports/common/ReportMailer.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportMailer.java b/src/main/java/org/traccar/reports/common/ReportMailer.java index 32bbd4b17..1723c0e3b 100644 --- a/src/main/java/org/traccar/reports/common/ReportMailer.java +++ b/src/main/java/org/traccar/reports/common/ReportMailer.java @@ -17,7 +17,6 @@ package org.traccar.reports.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.api.security.PermissionsService; import org.traccar.mail.MailManager; import org.traccar.model.User; import org.traccar.storage.Storage; -- cgit v1.2.3 From d0874767e27a021ee898201f8f5e27192e0da64b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 26 Jan 2023 07:55:48 -0800 Subject: Iridium without compression --- .../traccar/protocol/GalileoProtocolDecoder.java | 45 ++++++++++++++++++++-- .../protocol/GalileoProtocolDecoderTest.java | 23 ++++++++--- 2 files changed, 59 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index d4bd45c4f..44baa94ea 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -22,9 +22,11 @@ import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.BitBuffer; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Position; import org.traccar.session.DeviceSession; @@ -47,6 +49,17 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } private ByteBuf photo; + private boolean compressed; + + public void setCompressed(boolean compressed) { + this.compressed = compressed; + } + + public boolean getCompressed(long deviceId) { + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_EXTENDED.withPrefix(getProtocolName()), deviceId); + return value != null ? value : compressed; + } private static final Map TAG_LENGTH_MAP = new HashMap<>(); @@ -299,8 +312,34 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // accuracy buf.readUnsignedByte(); // data tag header - // ByteBuf data = buf.readSlice(buf.readUnsignedShort()); - // decodeMinimalDataSet(position, data); + ByteBuf data = buf.readSlice(buf.readUnsignedShort()); + if (getCompressed(deviceSession.getDeviceId())) { + + decodeMinimalDataSet(position, data); + + int[] tags = new int[BitUtil.to(data.readUnsignedByte(), 8)]; + for (int i = 0; i < tags.length; i++) { + tags[i] = data.readUnsignedByte(); + } + + for (int tag : tags) { + decodeTag(position, data, tag); + } + + } else { + + while (data.isReadable()) { + int tag = data.readUnsignedByte(); + if (tag == 0x30) { + position.setValid((data.readUnsignedByte() & 0xf0) == 0x00); + position.setLatitude(data.readIntLE() / 1000000.0); + position.setLongitude(data.readIntLE() / 1000000.0); + } else { + decodeTag(position, data, tag); + } + } + + } return position; } diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index df7f37903..7addc8e75 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -10,12 +10,6 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new GalileoProtocolDecoder(null)); - verifyPosition(decoder, binary( - "01004e01001c0747ea59333030323334303639363034353930000012000063c85e6903000b0321a8f846aba50000000202001e205f5ec863300c4643fdfdbbe6c8fb330000000034e7013505d400000000")); - - verifyNotNull(decoder, binary( - "01006501001c05cf1f8133303032333430363939303130313000004a000062d8f3ee03000b000f85402088970000000602003503333030323334303639393031303130100000207af3d862300cbe08ee00acfaf001330000760634b301350840090a416b2f42920e")); - verifyPositions(decoder, binary( "011801018202130338363833343530333230343234323604640010a406207caa9f5b300c830a7901ca0ec802330000000034b802350540003e41703f422b1043234504004600e09000000000a000a100a200a300a400a500a600a700a800a900aa00ab00ac00ad00ae00af00b00000b10000b20000b30000b40000b50000b60000b70000b80000b90000c000000000c100000000c200000000c300000000c400c500c600c700c800c900ca00cb00cc00cd00ce00cf00d000d100d200d4d3140000d60000d70000d80000d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000f400000000f500000000f600000000f700000000f800000000f9000000008960")); @@ -51,4 +45,21 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { } + @Test + public void testDecodeIridium() throws Exception { + + var decoder = inject(new GalileoProtocolDecoder(null)); + + decoder.setCompressed(false); + + verifyPosition(decoder, binary( + "01004e01001c0747ea59333030323334303639363034353930000012000063c85e6903000b0321a8f846aba50000000202001e205f5ec863300c4643fdfdbbe6c8fb330000000034e7013505d400000000")); + + /*decoder.setCompressed(true); + + verifyPosition(decoder, binary( + "01003a01001c07553e40333030323334303639363034353930020021000063d1921c03000b0321ac2c4545b20000009f02000ac200000000db00000000"));*/ + + } + } -- cgit v1.2.3 From 1d0d5661ca921a08217f23d4889f530643327847 Mon Sep 17 00:00:00 2001 From: Leo Sadovsky Date: Thu, 26 Jan 2023 20:34:12 +0300 Subject: worked out the review comments: code formatting and naming issues --- setup/default.xml | 1 - src/main/java/org/traccar/config/Keys.java | 1 - src/main/java/org/traccar/helper/Log.java | 8 +++----- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/setup/default.xml b/setup/default.xml index f2ca45fc3..c00d29384 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -24,7 +24,6 @@ info ./logs/tracker-server.log true - day true 86400 diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 19e4540ee..093f4298c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1584,7 +1584,6 @@ public final class Keys { List.of(KeyType.CONFIG), "day"); - /** * A list of position attributes to log. */ diff --git a/src/main/java/org/traccar/helper/Log.java b/src/main/java/org/traccar/helper/Log.java index a8bf66827..9aaf1cfd3 100644 --- a/src/main/java/org/traccar/helper/Log.java +++ b/src/main/java/org/traccar/helper/Log.java @@ -55,23 +55,21 @@ public final class Log { private String suffix; private Writer writer; private final boolean rotate; - - private final String logFileSuffix; + private final String template; RollingFileHandler(String name, boolean rotate, String rotateInterval) { this.name = name; this.rotate = rotate; - this.logFileSuffix = rotateInterval.equalsIgnoreCase("HOUR") ? "yyyyMMddHH" : "yyyyMMdd"; + this.template = rotateInterval.equalsIgnoreCase("HOUR") ? "yyyyMMddHH" : "yyyyMMdd"; } - @Override public synchronized void publish(LogRecord record) { if (isLoggable(record)) { try { String suffix = ""; if (rotate) { - suffix = new SimpleDateFormat(this.logFileSuffix).format(new Date(record.getMillis())); + suffix = new SimpleDateFormat(template).format(new Date(record.getMillis())); if (writer != null && !suffix.equals(this.suffix)) { writer.close(); writer = null; -- cgit v1.2.3 From 18387265cd9432a906cd16b7d71547be5bf46086 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 26 Jan 2023 15:19:47 -0800 Subject: Use period from calendar --- schema/changelog-5.6.xml | 6 --- src/main/java/org/traccar/model/Calendar.java | 16 ++++--- src/main/java/org/traccar/model/Report.java | 22 ---------- .../java/org/traccar/schedule/TaskReports.java | 51 ++++++++++------------ 4 files changed, 34 insertions(+), 61 deletions(-) (limited to 'src/main/java/org') diff --git a/schema/changelog-5.6.xml b/schema/changelog-5.6.xml index 38b206902..dc302c6a4 100644 --- a/schema/changelog-5.6.xml +++ b/schema/changelog-5.6.xml @@ -25,12 +25,6 @@ - - - - - - diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index c1f98a957..62c51cc4a 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -24,6 +24,7 @@ import net.fortuna.ical4j.filter.predicate.PeriodRule; import net.fortuna.ical4j.model.DateTime; import net.fortuna.ical4j.model.Period; import net.fortuna.ical4j.model.component.CalendarComponent; +import net.fortuna.ical4j.model.component.VEvent; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -32,6 +33,7 @@ import java.io.IOException; import java.time.Duration; import java.util.Collection; import java.util.Date; +import java.util.List; @StorageName("tc_calendars") public class Calendar extends ExtendedModel { @@ -66,14 +68,18 @@ public class Calendar extends ExtendedModel { return calendar; } - public boolean checkMoment(Date date) { + public Collection findEvents(Date date) { if (calendar != null) { Period period = new Period(new DateTime(date), Duration.ZERO); - Filter filter = new Filter<>(new PeriodRule<>(period)); - Collection events = filter.filter(calendar.getComponents(CalendarComponent.VEVENT)); - return events != null && !events.isEmpty(); + Filter filter = new Filter<>(new PeriodRule<>(period)); + return filter.filter(calendar.getComponents(CalendarComponent.VEVENT)); + } else { + return List.of(); } - return false; + } + + public boolean checkMoment(Date date) { + return !findEvents(date).isEmpty(); } } diff --git a/src/main/java/org/traccar/model/Report.java b/src/main/java/org/traccar/model/Report.java index 83bb2e920..1556ecc9e 100644 --- a/src/main/java/org/traccar/model/Report.java +++ b/src/main/java/org/traccar/model/Report.java @@ -17,8 +17,6 @@ package org.traccar.model; import org.traccar.storage.StorageName; -import java.util.Date; - @StorageName("tc_reports") public class Report extends ScheduledModel { @@ -42,24 +40,4 @@ public class Report extends ScheduledModel { this.description = description; } - private Date from; - - public Date getFrom() { - return from; - } - - public void setFrom(Date from) { - this.from = from; - } - - private Date to; - - public Date getTo() { - return to; - } - - public void setTo(Date to) { - this.to = to; - } - } diff --git a/src/main/java/org/traccar/schedule/TaskReports.java b/src/main/java/org/traccar/schedule/TaskReports.java index 259eb10d4..c80b786e9 100644 --- a/src/main/java/org/traccar/schedule/TaskReports.java +++ b/src/main/java/org/traccar/schedule/TaskReports.java @@ -15,6 +15,7 @@ */ package org.traccar.schedule; +import net.fortuna.ical4j.model.component.VEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.BaseModel; @@ -86,8 +87,15 @@ public class TaskReports implements ScheduleTask { for (Report report : storage.getObjects(Report.class, new Request(new Columns.All()))) { Calendar calendar = storage.getObject(Calendar.class, new Request( new Columns.All(), new Condition.Equals("id", report.getCalendarId()))); - if (calendar.checkMoment(currentCheck) && !calendar.checkMoment(lastCheck)) { - executeReport(report); + + var lastEvents = calendar.findEvents(lastCheck); + var currentEvents = calendar.findEvents(currentCheck); + + if (!lastEvents.isEmpty() && currentEvents.isEmpty()) { + VEvent event = lastEvents.iterator().next(); + Date from = event.getStartDate().getDate(); + Date to = event.getEndDate().getDate(); + executeReport(report, from, to); } } } catch (StorageException e) { @@ -95,7 +103,8 @@ public class TaskReports implements ScheduleTask { } } - private void executeReport(Report report) throws StorageException { + private void executeReport(Report report, Date from, Date to) throws StorageException { + var deviceIds = storage.getObjects(Device.class, new Request( new Columns.Include("id"), new Condition.Permission(Device.class, Report.class, report.getId()))) @@ -107,42 +116,28 @@ public class TaskReports implements ScheduleTask { var users = storage.getObjects(User.class, new Request( new Columns.Include("id"), new Condition.Permission(User.class, Report.class, report.getId()))); + for (User user : users) { switch (report.getType()) { case "events": - reportMailer.sendAsync(user.getId(), stream -> { - eventsReportProvider.getExcel( - stream, user.getId(), deviceIds, groupIds, - List.of(), report.getFrom(), report.getTo()); - }); + reportMailer.sendAsync(user.getId(), stream -> eventsReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, List.of(), from, to)); break; case "route": - reportMailer.sendAsync(user.getId(), stream -> { - routeReportProvider.getExcel( - stream, user.getId(), deviceIds, groupIds, - report.getFrom(), report.getTo()); - }); + reportMailer.sendAsync(user.getId(), stream -> routeReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, from, to)); break; case "summary": - reportMailer.sendAsync(user.getId(), stream -> { - summaryReportProvider.getExcel( - stream, user.getId(), deviceIds, groupIds, - report.getFrom(), report.getTo(), false); - }); + reportMailer.sendAsync(user.getId(), stream -> summaryReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, from, to, false)); break; case "trips": - reportMailer.sendAsync(user.getId(), stream -> { - tripsReportProvider.getExcel( - stream, user.getId(), deviceIds, groupIds, - report.getFrom(), report.getTo()); - }); + reportMailer.sendAsync(user.getId(), stream -> tripsReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, from, to)); break; case "stops": - reportMailer.sendAsync(user.getId(), stream -> { - stopsReportProvider.getExcel( - stream, user.getId(), deviceIds, groupIds, - report.getFrom(), report.getTo()); - }); + reportMailer.sendAsync(user.getId(), stream -> stopsReportProvider.getExcel( + stream, user.getId(), deviceIds, groupIds, from, to)); break; default: LOGGER.warn("Unsupported report type {}", report.getType()); -- cgit v1.2.3 From 0999180f58cf6a0edaf08461674eae70e839f3ce Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 Jan 2023 07:09:07 -0800 Subject: Disable scheduling task --- src/main/java/org/traccar/reports/common/ReportMailer.java | 14 +++++--------- src/main/java/org/traccar/schedule/ScheduleManager.java | 1 - 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportMailer.java b/src/main/java/org/traccar/reports/common/ReportMailer.java index 1723c0e3b..221b35ae1 100644 --- a/src/main/java/org/traccar/reports/common/ReportMailer.java +++ b/src/main/java/org/traccar/reports/common/ReportMailer.java @@ -17,13 +17,10 @@ package org.traccar.reports.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.api.security.PermissionsService; import org.traccar.mail.MailManager; import org.traccar.model.User; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; import javax.activation.DataHandler; import javax.inject.Inject; @@ -37,12 +34,12 @@ public class ReportMailer { private static final Logger LOGGER = LoggerFactory.getLogger(ReportMailer.class); - private final Storage storage; + private final PermissionsService permissionsService; private final MailManager mailManager; @Inject - public ReportMailer(Storage storage, MailManager mailManager) { - this.storage = storage; + public ReportMailer(PermissionsService permissionsService, MailManager mailManager) { + this.permissionsService = permissionsService; this.mailManager = mailManager; } @@ -57,8 +54,7 @@ public class ReportMailer { attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( stream.toByteArray(), "application/octet-stream"))); - User user = storage.getObject( - User.class, new Request(new Columns.All(), new Condition.Equals("id", userId))); + User user = permissionsService.getUser(userId); mailManager.sendMessage(user, "Report", "The report is in the attachment.", attachment); } catch (StorageException | IOException | MessagingException e) { LOGGER.warn("Email report failed", e); diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index e1de3b3af..450e531a0 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -39,7 +39,6 @@ public class ScheduleManager implements LifecycleObject { public void start() { executor = Executors.newSingleThreadScheduledExecutor(); var tasks = List.of( - TaskReports.class, TaskDeviceInactivityCheck.class, TaskWebSocketKeepalive.class, TaskHealthCheck.class); -- cgit v1.2.3 From d66d04b400654169e3aab6803311b39dc0f788f4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 Jan 2023 07:20:22 -0800 Subject: Fix report task injection --- .../java/org/traccar/schedule/ScheduleManager.java | 1 + .../java/org/traccar/schedule/TaskReports.java | 37 +++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 450e531a0..e1de3b3af 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -39,6 +39,7 @@ public class ScheduleManager implements LifecycleObject { public void start() { executor = Executors.newSingleThreadScheduledExecutor(); var tasks = List.of( + TaskReports.class, TaskDeviceInactivityCheck.class, TaskWebSocketKeepalive.class, TaskHealthCheck.class); diff --git a/src/main/java/org/traccar/schedule/TaskReports.java b/src/main/java/org/traccar/schedule/TaskReports.java index c80b786e9..004a6078c 100644 --- a/src/main/java/org/traccar/schedule/TaskReports.java +++ b/src/main/java/org/traccar/schedule/TaskReports.java @@ -15,6 +15,9 @@ */ package org.traccar.schedule; +import com.google.inject.Injector; +import com.google.inject.servlet.RequestScoper; +import com.google.inject.servlet.ServletScopes; import net.fortuna.ical4j.model.component.VEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,6 +40,7 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.concurrent.ScheduledExecutorService; @@ -50,27 +54,12 @@ public class TaskReports implements ScheduleTask { private static final long CHECK_PERIOD_MINUTES = 1; private final Storage storage; - private final ReportMailer reportMailer; + private final Injector injector; @Inject - private EventsReportProvider eventsReportProvider; - - @Inject - private RouteReportProvider routeReportProvider; - - @Inject - private StopsReportProvider stopsReportProvider; - - @Inject - private SummaryReportProvider summaryReportProvider; - - @Inject - private TripsReportProvider tripsReportProvider; - - @Inject - public TaskReports(Storage storage, ReportMailer reportMailer) { + public TaskReports(Storage storage, Injector injector) { this.storage = storage; - this.reportMailer = reportMailer; + this.injector = injector; } @Override @@ -95,7 +84,10 @@ public class TaskReports implements ScheduleTask { VEvent event = lastEvents.iterator().next(); Date from = event.getStartDate().getDate(); Date to = event.getEndDate().getDate(); - executeReport(report, from, to); + RequestScoper scope = ServletScopes.scopeRequest(Collections.emptyMap()); + try (RequestScoper.CloseableScope ignored = scope.open()) { + executeReport(report, from, to); + } } } } catch (StorageException e) { @@ -117,25 +109,32 @@ public class TaskReports implements ScheduleTask { new Columns.Include("id"), new Condition.Permission(User.class, Report.class, report.getId()))); + ReportMailer reportMailer = injector.getInstance(ReportMailer.class); + for (User user : users) { switch (report.getType()) { case "events": + var eventsReportProvider = injector.getInstance(EventsReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> eventsReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, List.of(), from, to)); break; case "route": + var routeReportProvider = injector.getInstance(RouteReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> routeReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to)); break; case "summary": + var summaryReportProvider = injector.getInstance(SummaryReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> summaryReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to, false)); break; case "trips": + var tripsReportProvider = injector.getInstance(TripsReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> tripsReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to)); break; case "stops": + var stopsReportProvider = injector.getInstance(StopsReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> stopsReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to)); break; -- cgit v1.2.3 From 5a46718d48e2886d7bd37acd8c52f20c5c9e18bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 Jan 2023 14:23:56 -0800 Subject: Scheduled reports API --- src/main/java/org/traccar/api/resource/ReportResource.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 6944de9cb..b85e9a857 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -16,12 +16,11 @@ */ package org.traccar.api.resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.api.BaseResource; +import org.traccar.api.SimpleObjectResource; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.Report; import org.traccar.model.UserRestrictions; import org.traccar.reports.EventsReportProvider; import org.traccar.reports.RouteReportProvider; @@ -54,9 +53,7 @@ import java.util.List; @Path("reports") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class ReportResource extends BaseResource { - - private static final Logger LOGGER = LoggerFactory.getLogger(ReportResource.class); +public class ReportResource extends SimpleObjectResource { private static final String EXCEL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; @@ -78,6 +75,10 @@ public class ReportResource extends BaseResource { @Inject private ReportMailer reportMailer; + public ReportResource() { + super(Report.class); + } + private Response executeReport(long userId, boolean mail, ReportExecutor executor) { if (mail) { reportMailer.sendAsync(userId, executor); -- cgit v1.2.3 From 42cfe6de84f705971a638e5840d647a9e9c29c05 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 28 Jan 2023 07:49:38 -0800 Subject: Upgrade velocity engine --- build.gradle | 4 +- src/main/java/org/traccar/MainModule.java | 2 - .../java/org/traccar/helper/ServletHelperTest.java | 48 +++++----------------- 3 files changed, 13 insertions(+), 41 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 91ba2cd5c..4beab09be 100644 --- a/build.gradle +++ b/build.gradle @@ -69,8 +69,8 @@ dependencies { implementation "com.sun.mail:jakarta.mail:1.6.7" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) implementation "org.jxls:jxls-poi:1.0.16" // needs upgrade (wait for jexl 4) - implementation "org.apache.velocity:velocity:1.7" // needs upgrade - implementation "org.apache.velocity:velocity-tools:2.0" // needs upgrade + implementation 'org.apache.velocity:velocity-engine-core:2.3' + implementation 'org.apache.velocity.tools:velocity-tools-generic:3.1' implementation "org.apache.commons:commons-collections4:4.4" implementation "org.mnode.ical4j:ical4j:3.2.7" implementation "org.locationtech.spatial4j:spatial4j:0.8" diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 55211d109..db66e9e5f 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -26,7 +26,6 @@ import com.google.inject.name.Names; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.apache.velocity.app.VelocityEngine; -import org.apache.velocity.runtime.log.NullLogChute; import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.broadcast.MulticastBroadcastService; @@ -361,7 +360,6 @@ public class MainModule extends AbstractModule { public static VelocityEngine provideVelocityEngine(Config config) { Properties properties = new Properties(); properties.setProperty("file.resource.loader.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); - properties.setProperty("runtime.log.logsystem.class", NullLogChute.class.getName()); if (config.hasKey(Keys.WEB_URL)) { properties.setProperty("web.url", config.getString(Keys.WEB_URL).replaceAll("/$", "")); diff --git a/src/test/java/org/traccar/helper/ServletHelperTest.java b/src/test/java/org/traccar/helper/ServletHelperTest.java index e419b6491..55b96a41a 100644 --- a/src/test/java/org/traccar/helper/ServletHelperTest.java +++ b/src/test/java/org/traccar/helper/ServletHelperTest.java @@ -1,65 +1,39 @@ package org.traccar.helper; -import org.apache.struts.mock.MockHttpServletRequest; import org.junit.Test; -import java.util.HashMap; -import java.util.Map; +import javax.servlet.http.HttpServletRequest; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class ServletHelperTest { @Test public void testRetrieveRemoteAddressProxyMultiple() { - MockRequest request = new MockRequest(); - request.setRemoteAddress("147.120.1.5"); - request.addHeader("X-FORWARDED-FOR", "231.23.45.65, 10.20.10.33, 10.20.20.34"); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("147.120.1.5"); + when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65, 10.20.10.33, 10.20.20.34"); assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); } @Test public void testRetrieveRemoteAddressProxySingle() { - MockRequest request = new MockRequest(); - request.setRemoteAddress("147.120.1.5"); - request.addHeader("X-FORWARDED-FOR", "231.23.45.65"); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("147.120.1.5"); + when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65"); assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); } @Test public void testRetrieveRemoteAddressNoProxy() { - MockRequest request = new MockRequest(); - request.setRemoteAddress("231.23.45.65"); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("231.23.45.65"); assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); } - private final static class MockRequest extends MockHttpServletRequest { - - private String remoteAddress; - - private Map headers = new HashMap<>(); - - public void setRemoteAddress(String remoteAddress) { - this.remoteAddress = remoteAddress; - } - - public void addHeader(String name, String value) { - headers.put(name, value); - } - - @Override - public String getHeader(String name) { - return headers.get(name); - } - - @Override - public String getRemoteAddr() { - return remoteAddress; - } - - } - } -- cgit v1.2.3 From cd3eb2adb664a7c5278a2df124a589f6ba984c93 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 29 Jan 2023 08:08:45 -0800 Subject: Fix warning --- src/main/java/org/traccar/MainModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index db66e9e5f..ae637b455 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -359,7 +359,7 @@ public class MainModule extends AbstractModule { @Provides public static VelocityEngine provideVelocityEngine(Config config) { Properties properties = new Properties(); - properties.setProperty("file.resource.loader.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); + properties.setProperty("resource.loader.file.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); if (config.hasKey(Keys.WEB_URL)) { properties.setProperty("web.url", config.getString(Keys.WEB_URL).replaceAll("/$", "")); -- cgit v1.2.3 From f4f1b05f8d5211476ae073d8a3c2dbd10cbcbe8a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 29 Jan 2023 09:33:16 -0800 Subject: Upgrade JXLS library --- build.gradle | 5 +++-- .../traccar/handler/ComputedAttributesHandler.java | 24 ++++++++++++---------- .../traccar/handler/ComputedAttributesTest.java | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 0ac074f20..1a904d661 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,7 @@ ext { jerseyVersion = "2.37" // jersey 3 javax to jakarta jacksonVersion = "2.13.4" // same version as jersey-media-json-jackson dependency protobufVersion = "3.21.9" + jxlsVersion = "2.12.0" } sourceCompatibility = "11" @@ -67,8 +68,8 @@ dependencies { implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" implementation "org.liquibase:liquibase-core:4.17.2" implementation "com.sun.mail:jakarta.mail:1.6.7" - implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) - implementation "org.jxls:jxls-poi:1.0.16" // needs upgrade (wait for jexl 4) + implementation "org.jxls:jxls:$jxlsVersion" + implementation "org.jxls:jxls-poi:$jxlsVersion" implementation 'org.apache.velocity:velocity-engine-core:2.3' implementation 'org.apache.velocity.tools:velocity-tools-generic:3.1' implementation "org.apache.commons:commons-collections4:4.4" diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 620852502..ca6c0fc74 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -26,9 +26,10 @@ import java.util.Map; import java.util.Set; import io.netty.channel.ChannelHandler; -import org.apache.commons.jexl2.JexlEngine; -import org.apache.commons.jexl2.JexlException; -import org.apache.commons.jexl2.MapContext; +import org.apache.commons.jexl3.JexlBuilder; +import org.apache.commons.jexl3.JexlEngine; +import org.apache.commons.jexl3.JexlException; +import org.apache.commons.jexl3.MapContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; @@ -57,9 +58,10 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Inject public ComputedAttributesHandler(Config config, CacheManager cacheManager) { this.cacheManager = cacheManager; - engine = new JexlEngine(); - engine.setStrict(true); - engine.setFunctions(Collections.singletonMap("math", Math.class)); + engine = new JexlBuilder() + .strict(true) + .namespaces(Collections.singletonMap("math", Math.class)) + .create(); includeDeviceAttributes = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES); } @@ -68,13 +70,13 @@ public class ComputedAttributesHandler extends BaseDataHandler { if (includeDeviceAttributes) { Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device != null) { - for (Object key : device.getAttributes().keySet()) { - result.set((String) key, device.getAttributes().get(key)); + for (String key : device.getAttributes().keySet()) { + result.set(key, device.getAttributes().get(key)); } } } Set methods = new HashSet<>(Arrays.asList(position.getClass().getMethods())); - methods.removeAll(Arrays.asList(Object.class.getMethods())); + Arrays.asList(Object.class.getMethods()).forEach(methods::remove); for (Method method : methods) { if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { String name = Character.toLowerCase(method.getName().charAt(3)) + method.getName().substring(4); @@ -83,8 +85,8 @@ public class ComputedAttributesHandler extends BaseDataHandler { if (!method.getReturnType().equals(Map.class)) { result.set(name, method.invoke(position)); } else { - for (Object key : ((Map) method.invoke(position)).keySet()) { - result.set((String) key, ((Map) method.invoke(position)).get(key)); + for (Object key : ((Map) method.invoke(position)).keySet()) { + result.set((String) key, ((Map) method.invoke(position)).get(key)); } } } catch (IllegalAccessException | InvocationTargetException error) { diff --git a/src/test/java/org/traccar/handler/ComputedAttributesTest.java b/src/test/java/org/traccar/handler/ComputedAttributesTest.java index 2668c4f14..0beef9c57 100644 --- a/src/test/java/org/traccar/handler/ComputedAttributesTest.java +++ b/src/test/java/org/traccar/handler/ComputedAttributesTest.java @@ -41,7 +41,7 @@ public class ComputedAttributesTest { attribute.setExpression("(bitFlag & 4) != 0"); assertEquals(true, handler.computeAttribute(attribute, position)); - attribute.setExpression("if (event == 42) \"lowBattery\""); + attribute.setExpression("event == 42 ? \"lowBattery\" : null"); assertEquals("lowBattery", handler.computeAttribute(attribute, position)); attribute.setExpression("speed > 5 && valid"); -- cgit v1.2.3 From bcf1daf348c9a83892b1b0e214052327529d7064 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 31 Jan 2023 15:03:48 -0800 Subject: Improve test emails --- src/main/java/org/traccar/mail/LogMailManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/mail/LogMailManager.java b/src/main/java/org/traccar/mail/LogMailManager.java index b6b912d6c..4af68809c 100644 --- a/src/main/java/org/traccar/mail/LogMailManager.java +++ b/src/main/java/org/traccar/mail/LogMailManager.java @@ -38,7 +38,9 @@ public class LogMailManager implements MailManager { @Override public void sendMessage(User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { - LOGGER.info("\nTo: " + user.getEmail() + "\nSubject: " + subject + "\nBody:\n" + body); + LOGGER.info( + "Email sent\nTo: {}\nSubject: {}\nAttachment: {}\nBody:\n{}", + user.getEmail(), subject, attachment != null ? attachment.getFileName() : null, body); } } -- cgit v1.2.3 From 707fccfa5b8d3afaff10f70a65e6d99ed0df6561 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Feb 2023 13:42:29 -0800 Subject: Add combined report --- .../org/traccar/api/resource/ReportResource.java | 17 ++++++ .../traccar/reports/CombinedReportProvider.java | 70 ++++++++++++++++++++++ .../traccar/reports/model/CombinedReportItem.java | 54 +++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 src/main/java/org/traccar/reports/CombinedReportProvider.java create mode 100644 src/main/java/org/traccar/reports/model/CombinedReportItem.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index b85e9a857..e392f3f90 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -22,6 +22,7 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.Report; import org.traccar.model.UserRestrictions; +import org.traccar.reports.CombinedReportProvider; import org.traccar.reports.EventsReportProvider; import org.traccar.reports.RouteReportProvider; import org.traccar.reports.StopsReportProvider; @@ -29,6 +30,7 @@ import org.traccar.reports.SummaryReportProvider; import org.traccar.reports.TripsReportProvider; import org.traccar.reports.common.ReportExecutor; import org.traccar.reports.common.ReportMailer; +import org.traccar.reports.model.CombinedReportItem; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.SummaryReportItem; import org.traccar.reports.model.TripReportItem; @@ -57,6 +59,9 @@ public class ReportResource extends SimpleObjectResource { private static final String EXCEL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + @Inject + private CombinedReportProvider combinedReportProvider; + @Inject private EventsReportProvider eventsReportProvider; @@ -96,6 +101,18 @@ public class ReportResource extends SimpleObjectResource { } } + @Path("combined") + @GET + public Collection getCombined( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); + LogAction.logReport(getUserId(), "combined", from, to, deviceIds, groupIds); + return combinedReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); + } + @Path("route") @GET public Collection getRoute( diff --git a/src/main/java/org/traccar/reports/CombinedReportProvider.java b/src/main/java/org/traccar/reports/CombinedReportProvider.java new file mode 100644 index 000000000..ca290f7db --- /dev/null +++ b/src/main/java/org/traccar/reports/CombinedReportProvider.java @@ -0,0 +1,70 @@ +/* + * 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.reports; + +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.CombinedReportItem; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.stream.Collectors; + +public class CombinedReportProvider { + + private final ReportUtils reportUtils; + private final Storage storage; + + @Inject + public CombinedReportProvider(ReportUtils reportUtils, Storage storage) { + this.reportUtils = reportUtils; + this.storage = storage; + } + + public Collection getObjects( + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { + reportUtils.checkPeriodLimit(from, to); + + ArrayList result = new ArrayList<>(); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + CombinedReportItem item = new CombinedReportItem(); + item.setDeviceId(device.getId()); + item.setRoute(PositionUtil.getPositions(storage, device.getId(), from, to) + .stream() + .map(p -> new double[] { p.getLongitude(), p.getLatitude() }) + .collect(Collectors.toList())); + item.setEvents(storage.getObjects(Event.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", device.getId()), + new Condition.Between("eventTime", "from", from, "to", to)), + new Order("eventTime")))); + result.add(item); + } + return result; + } +} diff --git a/src/main/java/org/traccar/reports/model/CombinedReportItem.java b/src/main/java/org/traccar/reports/model/CombinedReportItem.java new file mode 100644 index 000000000..00f2cc08e --- /dev/null +++ b/src/main/java/org/traccar/reports/model/CombinedReportItem.java @@ -0,0 +1,54 @@ +/* + * 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.reports.model; + +import org.traccar.model.Event; + +import java.util.List; + +public class CombinedReportItem { + + private long deviceId; + + public long getDeviceId() { + return deviceId; + } + + public void setDeviceId(long deviceId) { + this.deviceId = deviceId; + } + + private List route; + + public List getRoute() { + return route; + } + + public void setRoute(List route) { + this.route = route; + } + + private List events; + + public List getEvents() { + return events; + } + + public void setEvents(List events) { + this.events = events; + } + +} -- cgit v1.2.3 From 47c9d9fb21e897733f7aaa29bb5797036ccc4476 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Feb 2023 13:56:18 -0800 Subject: Add event positions --- .../org/traccar/reports/CombinedReportProvider.java | 18 +++++++++++++----- .../org/traccar/reports/model/CombinedReportItem.java | 11 +++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/CombinedReportProvider.java b/src/main/java/org/traccar/reports/CombinedReportProvider.java index ca290f7db..d47a91bef 100644 --- a/src/main/java/org/traccar/reports/CombinedReportProvider.java +++ b/src/main/java/org/traccar/reports/CombinedReportProvider.java @@ -53,16 +53,24 @@ public class CombinedReportProvider { for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { CombinedReportItem item = new CombinedReportItem(); item.setDeviceId(device.getId()); - item.setRoute(PositionUtil.getPositions(storage, device.getId(), from, to) - .stream() - .map(p -> new double[] { p.getLongitude(), p.getLatitude() }) + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); + item.setRoute(positions.stream() + .map(p -> new double[] {p.getLongitude(), p.getLatitude()}) .collect(Collectors.toList())); - item.setEvents(storage.getObjects(Event.class, new Request( + var events = storage.getObjects(Event.class, new Request( new Columns.All(), new Condition.And( new Condition.Equals("deviceId", device.getId()), new Condition.Between("eventTime", "from", from, "to", to)), - new Order("eventTime")))); + new Order("eventTime"))); + item.setEvents(events); + var eventPositions = events.stream() + .map(Event::getPositionId) + .filter(positionId -> positionId > 0) + .collect(Collectors.toSet()); + item.setPositions(positions.stream() + .filter(p -> eventPositions.contains(p.getId())) + .collect(Collectors.toList())); result.add(item); } return result; diff --git a/src/main/java/org/traccar/reports/model/CombinedReportItem.java b/src/main/java/org/traccar/reports/model/CombinedReportItem.java index 00f2cc08e..810e00916 100644 --- a/src/main/java/org/traccar/reports/model/CombinedReportItem.java +++ b/src/main/java/org/traccar/reports/model/CombinedReportItem.java @@ -16,6 +16,7 @@ package org.traccar.reports.model; import org.traccar.model.Event; +import org.traccar.model.Position; import java.util.List; @@ -51,4 +52,14 @@ public class CombinedReportItem { this.events = events; } + private List positions; + + public List getPositions() { + return positions; + } + + public void setPositions(List positions) { + this.positions = positions; + } + } -- cgit v1.2.3 From 5e690d9b586c191bc620260a2b7551d52f8d28a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Feb 2023 14:19:38 -0800 Subject: Filter no location events --- src/main/java/org/traccar/reports/CombinedReportProvider.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/CombinedReportProvider.java b/src/main/java/org/traccar/reports/CombinedReportProvider.java index d47a91bef..afe146e91 100644 --- a/src/main/java/org/traccar/reports/CombinedReportProvider.java +++ b/src/main/java/org/traccar/reports/CombinedReportProvider.java @@ -63,10 +63,11 @@ public class CombinedReportProvider { new Condition.Equals("deviceId", device.getId()), new Condition.Between("eventTime", "from", from, "to", to)), new Order("eventTime"))); - item.setEvents(events); + item.setEvents(events.stream() + .filter(p -> p.getPositionId() > 0) + .collect(Collectors.toList())); var eventPositions = events.stream() .map(Event::getPositionId) - .filter(positionId -> positionId > 0) .collect(Collectors.toSet()); item.setPositions(positions.stream() .filter(p -> eventPositions.contains(p.getId())) -- cgit v1.2.3 From 7f7e5a5d479e58e83c8f0f5b81e230f1ed460478 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Feb 2023 14:25:38 -0800 Subject: Fix fuel events --- src/main/java/org/traccar/handler/events/FuelEventHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java index 462cc4223..a1584d4e4 100644 --- a/src/main/java/org/traccar/handler/events/FuelEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 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. @@ -60,13 +60,13 @@ public class FuelEventHandler extends BaseEventHandler { if (change > 0) { double threshold = AttributeUtil.lookup( cacheManager, Keys.EVENT_FUEL_INCREASE_THRESHOLD, position.getDeviceId()); - if (change >= threshold) { + if (threshold > 0 && change >= threshold) { return Map.of(new Event(Event.TYPE_DEVICE_FUEL_INCREASE, position), position); } } else if (change < 0) { double threshold = AttributeUtil.lookup( cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); - if (Math.abs(change) >= threshold) { + if (threshold > 0 && Math.abs(change) >= threshold) { return Map.of(new Event(Event.TYPE_DEVICE_FUEL_DROP, position), position); } } -- cgit v1.2.3 From 74008e1053d49b407eb8eb44d7d60537bdf22047 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Feb 2023 14:50:02 -0800 Subject: Exclude event types --- src/main/java/org/traccar/reports/CombinedReportProvider.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/CombinedReportProvider.java b/src/main/java/org/traccar/reports/CombinedReportProvider.java index afe146e91..923fd12b4 100644 --- a/src/main/java/org/traccar/reports/CombinedReportProvider.java +++ b/src/main/java/org/traccar/reports/CombinedReportProvider.java @@ -31,10 +31,13 @@ import javax.inject.Inject; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.Set; import java.util.stream.Collectors; public class CombinedReportProvider { + private static final Set EXCLUDE_TYPES = Set.of(Event.TYPE_DEVICE_MOVING); + private final ReportUtils reportUtils; private final Storage storage; @@ -64,7 +67,7 @@ public class CombinedReportProvider { new Condition.Between("eventTime", "from", from, "to", to)), new Order("eventTime"))); item.setEvents(events.stream() - .filter(p -> p.getPositionId() > 0) + .filter(e -> e.getPositionId() > 0 && !EXCLUDE_TYPES.contains(e.getType())) .collect(Collectors.toList())); var eventPositions = events.stream() .map(Event::getPositionId) -- cgit v1.2.3 From 1e354ec746635b5773150ac4169ac7468cb227b9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Feb 2023 07:27:20 -0800 Subject: Fix temperature decoding --- src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index cb0e10042..db1b365c3 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -314,7 +314,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { } if (buf.readableBytes() >= 12) { - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort() / 256.0); + position.set(Position.PREFIX_TEMP + 1, buf.readShort() / 256.0); position.set("humidity", buf.readUnsignedShort() * 0.1); position.set("illuminance", buf.readUnsignedInt() / 256.0); position.set("co2", buf.readUnsignedInt()); -- cgit v1.2.3 From 514582dd83c4520948c03eb3fc84444e0d7f5a49 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Feb 2023 17:49:45 -0800 Subject: Tramigo T24 frame decoder --- src/main/java/org/traccar/protocol/TramigoFrameDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java index e4c94dc77..4b0fe52b3 100644 --- a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -33,7 +33,7 @@ public class TramigoFrameDecoder extends BaseFrameDecoder { if (buf.getUnsignedByte(buf.readerIndex()) == 0x80) { length = buf.getUnsignedShortLE(buf.readerIndex() + 6); } else { - length = buf.getUnsignedShort(buf.readerIndex() + 6); + length = buf.getUnsignedShortLE(buf.readerIndex() + 1); } if (length <= buf.readableBytes()) { diff --git a/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java index a093d94e9..cf997c237 100644 --- a/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java @@ -10,6 +10,10 @@ public class TramigoFrameDecoderTest extends ProtocolTest { var decoder = inject(new TramigoFrameDecoder()); + verifyFrame( + binary("0480001df35b1b69101a023ef34f0090436d38003200380e0000850081c0e4ff6d542f00000015000000050000000000007600a20100008f436d3800014400000000000000000021000a0006005a574a6169726f7320486972692043656e747265205072696d617279205363686f6f6c536f7574686572746f6e486172617265"), + decoder.decode(null, null, binary("0480001df35b1b69101a023ef34f0090436d38003200380e0000850081c0e4ff6d542f00000015000000050000000000007600a20100008f436d3800014400000000000000000021000a0006005a574a6169726f7320486972692043656e747265205072696d617279205363686f6f6c536f7574686572746f6e486172617265"))); + verifyFrame( binary("8000ed2bb0009c000101bee000050b09633d925b5472616d69676f3a205472697020737461727465642c2053686f636b2053656e736f722c206174204b696e6720437265656b20526f61642d46726565746f776e205374726565742c20506f727420486172636f7572742c205269766572732c204e472c20342e37363336312c20372e30313836382c2030373a31383a333620536570203320454f46"), decoder.decode(null, null, binary("8000ed2bb0009c000101bee000050b09633d925b5472616d69676f3a205472697020737461727465642c2053686f636b2053656e736f722c206174204b696e6720437265656b20526f61642d46726565746f776e205374726565742c20506f727420486172636f7572742c205269766572732c204e472c20342e37363336312c20372e30313836382c2030373a31383a333620536570203320454f46"))); -- cgit v1.2.3 From b2824862bb72e7521a61d047235d2dc8ac4c52cd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Feb 2023 09:50:21 -0800 Subject: Refactor Tramigo decoder --- .../org/traccar/protocol/TramigoFrameDecoder.java | 8 +- .../traccar/protocol/TramigoProtocolDecoder.java | 155 +++++++++++++-------- .../protocol/TramigoProtocolDecoderTest.java | 3 + 3 files changed, 104 insertions(+), 62 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java index 4b0fe52b3..72cadf21a 100644 --- a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java @@ -29,11 +29,15 @@ public class TramigoFrameDecoder extends BaseFrameDecoder { return null; } + int protocol = buf.getUnsignedByte(buf.readerIndex()); + int length; - if (buf.getUnsignedByte(buf.readerIndex()) == 0x80) { + if (protocol == 0x80) { length = buf.getUnsignedShortLE(buf.readerIndex() + 6); - } else { + } else if (protocol == 0x02 || protocol == 0x04) { length = buf.getUnsignedShortLE(buf.readerIndex() + 1); + } else { + length = buf.getUnsignedShort(buf.readerIndex() + 6); } if (length <= buf.readableBytes()) { diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index 21dd78da3..7be2cd092 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 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,6 +29,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @@ -54,28 +55,39 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; int protocol = buf.readUnsignedByte(); - boolean legacy = protocol == 0x80; + + if (protocol == 0x01) { + return decode01(channel, remoteAddress, buf); + } else if (protocol == 0x80) { + return decode80(channel, remoteAddress, buf); + } + + return null; + } + + private Position decode01(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedByte(); // version id - int index = legacy ? buf.readUnsignedShort() : buf.readUnsignedShortLE(); - int type = legacy ? buf.readUnsignedShort() : buf.readUnsignedShortLE(); - buf.readUnsignedShort(); // length - buf.readUnsignedShort(); // mask - buf.readUnsignedShort(); // checksum - long id = legacy ? buf.readUnsignedInt() : buf.readUnsignedIntLE(); - buf.readUnsignedInt(); // time + int index = buf.readUnsignedShortLE(); + int type = buf.readUnsignedShortLE(); - Position position = new Position(getProtocolName()); - position.set(Position.KEY_INDEX, index); - position.setValid(true); + if (type == MSG_COMPACT || type == MSG_FULL) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); + buf.readUnsignedShort(); // length + buf.readUnsignedShort(); // mask + buf.readUnsignedShort(); // checksum + long id = buf.readUnsignedIntLE(); + buf.readUnsignedInt(); // time - if (protocol == 0x01 && (type == MSG_COMPACT || type == MSG_FULL)) { + Position position = new Position(getProtocolName()); + position.set(Position.KEY_INDEX, index); + position.setValid(true); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); // need to send ack? @@ -105,56 +117,79 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (legacy) { + } - if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Unpooled.copiedBuffer("gprs,ack," + index, StandardCharsets.US_ASCII), remoteAddress)); - } + return null; - String sentence = buf.toString(StandardCharsets.US_ASCII); + } - Pattern pattern = Pattern.compile("(-?\\d+\\.\\d+), (-?\\d+\\.\\d+)"); - Matcher matcher = pattern.matcher(sentence); - if (!matcher.find()) { - return null; - } - position.setLatitude(Double.parseDouble(matcher.group(1))); - position.setLongitude(Double.parseDouble(matcher.group(2))); - - pattern = Pattern.compile("([NSWE]{1,2}) with speed (\\d+) km/h"); - matcher = pattern.matcher(sentence); - if (matcher.find()) { - for (int i = 0; i < DIRECTIONS.length; i++) { - if (matcher.group(1).equals(DIRECTIONS[i])) { - position.setCourse(i * 45.0); - break; - } - } - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(matcher.group(2)))); - } + private Position decode80(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws ParseException { - pattern = Pattern.compile("(\\d{1,2}:\\d{2}(:\\d{2})? \\w{3} \\d{1,2})"); - matcher = pattern.matcher(sentence); - if (!matcher.find()) { - return null; - } - DateFormat dateFormat = new SimpleDateFormat( - matcher.group(2) != null ? "HH:mm:ss MMM d yyyy" : "HH:mm MMM d yyyy", Locale.ENGLISH); - position.setTime(DateUtil.correctYear( - dateFormat.parse(matcher.group(1) + " " + Calendar.getInstance().get(Calendar.YEAR)))); - - if (sentence.contains("Ignition on detected")) { - position.set(Position.KEY_IGNITION, true); - } else if (sentence.contains("Ignition off detected")) { - position.set(Position.KEY_IGNITION, false); - } + buf.readUnsignedByte(); // version id + int index = buf.readUnsignedShort(); + buf.readUnsignedShort(); // type - return position; + buf.readUnsignedShort(); // length + buf.readUnsignedShort(); // mask + buf.readUnsignedShort(); // checksum + long id = buf.readUnsignedInt(); + buf.readUnsignedInt(); // time + + Position position = new Position(getProtocolName()); + position.set(Position.KEY_INDEX, index); + position.setValid(true); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage( + Unpooled.copiedBuffer("gprs,ack," + index, StandardCharsets.US_ASCII), remoteAddress)); } - return null; + String sentence = buf.toString(StandardCharsets.US_ASCII); + + Pattern pattern = Pattern.compile("(-?\\d+\\.\\d+), (-?\\d+\\.\\d+)"); + Matcher matcher = pattern.matcher(sentence); + if (!matcher.find()) { + return null; + } + position.setLatitude(Double.parseDouble(matcher.group(1))); + position.setLongitude(Double.parseDouble(matcher.group(2))); + + pattern = Pattern.compile("([NSWE]{1,2}) with speed (\\d+) km/h"); + matcher = pattern.matcher(sentence); + if (matcher.find()) { + for (int i = 0; i < DIRECTIONS.length; i++) { + if (matcher.group(1).equals(DIRECTIONS[i])) { + position.setCourse(i * 45.0); + break; + } + } + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(matcher.group(2)))); + } + + pattern = Pattern.compile("(\\d{1,2}:\\d{2}(:\\d{2})? \\w{3} \\d{1,2})"); + matcher = pattern.matcher(sentence); + if (!matcher.find()) { + return null; + } + DateFormat dateFormat = new SimpleDateFormat( + matcher.group(2) != null ? "HH:mm:ss MMM d yyyy" : "HH:mm MMM d yyyy", Locale.ENGLISH); + position.setTime(DateUtil.correctYear( + dateFormat.parse(matcher.group(1) + " " + Calendar.getInstance().get(Calendar.YEAR)))); + + if (sentence.contains("Ignition on detected")) { + position.set(Position.KEY_IGNITION, true); + } else if (sentence.contains("Ignition off detected")) { + position.set(Position.KEY_IGNITION, false); + } + + return position; + } } diff --git a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java index c2d13d199..db3c5c32f 100644 --- a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TramigoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TramigoProtocolDecoder(null)); + verifyNull(decoder, binary( + "0480001df35b1b69101a023ef34f0090436d38003200380e0000850081c0e4ff6d542f00000015000000050000000000007600a20100008f436d3800014400000000000000000021000a0006005a574a6169726f7320486972692043656e747265205072696d617279205363686f6f6c536f7574686572746f6e486172617265")); + verifyAttributes(decoder, binary( "8000c426b000a6000101c557037598050d5c8a595472616d69676f3a204d6f76696e672c20302e3132206b6d2045206f66204c617275742054696e2049736c616d6963205072696d617279205363686f6f6c2c2054616970696e672c20506572616b2c204d592c20342e38333134392c203130302e37333038352c204e572077697468207370656564203130206b6d2f682c2030303a34393a30382041756720392020454f46")); -- cgit v1.2.3 From f4b97f7aa63ce5facd4ce02bb0c16d17c3e39b74 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Feb 2023 10:40:00 -0800 Subject: Tramigo M2Mv2 implementation --- .../traccar/protocol/TramigoProtocolDecoder.java | 106 ++++++++++++++++++--- .../protocol/TramigoProtocolDecoderTest.java | 4 +- 2 files changed, 96 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index 7be2cd092..1296929bc 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BitUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -43,9 +44,6 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - public static final int MSG_COMPACT = 0x0100; - public static final int MSG_FULL = 0x00FE; - private static final String[] DIRECTIONS = new String[] {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}; @Override @@ -58,6 +56,8 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { if (protocol == 0x01) { return decode01(channel, remoteAddress, buf); + } else if (protocol == 0x04) { + return decode04(channel, remoteAddress, buf); } else if (protocol == 0x80) { return decode80(channel, remoteAddress, buf); } @@ -71,7 +71,7 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { int index = buf.readUnsignedShortLE(); int type = buf.readUnsignedShortLE(); - if (type == MSG_COMPACT || type == MSG_FULL) { + if (type == 0x0100 || type == 0x00FE) { buf.readUnsignedShort(); // length buf.readUnsignedShort(); // mask @@ -79,21 +79,21 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { long id = buf.readUnsignedIntLE(); buf.readUnsignedInt(); // time - Position position = new Position(getProtocolName()); - position.set(Position.KEY_INDEX, index); - position.setValid(true); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_INDEX, index); // need to send ack? buf.readUnsignedShortLE(); // report trigger buf.readUnsignedShortLE(); // state flag + position.setValid(true); position.setLatitude(buf.readUnsignedIntLE() * 0.0000001); position.setLongitude(buf.readUnsignedIntLE() * 0.0000001); @@ -123,6 +123,88 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { } + private Position decode04(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws ParseException { + + buf.readUnsignedShortLE(); // length + buf.readUnsignedShortLE(); // checksum + int index = buf.readUnsignedShortLE(); + + String id = String.format("%08d%07d", buf.readUnsignedIntLE(), buf.readUnsignedIntLE()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_INDEX, index); + + position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); + + while (buf.isReadable()) { + int type = buf.readUnsignedByte(); + switch (type) { + case 0: + position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); + buf.readUnsignedIntLE(); // event data + + int status = buf.readUnsignedShortLE(); + position.set(Position.KEY_IGNITION, BitUtil.check(status, 5)); + position.set(Position.KEY_STATUS, status); + + position.setValid(true); + position.setLatitude(buf.readInt() * 0.00001); + position.setLongitude(buf.readInt() * 0.00001); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + position.setCourse(buf.readUnsignedShortLE()); + + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + position.set(Position.KEY_GPS, buf.readUnsignedByte()); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShortLE()); + position.set("maxAcceleration", buf.readUnsignedShortLE() * 0.001); + position.set("maxDeceleration", buf.readUnsignedShortLE() * 0.001); + buf.readUnsignedShortLE(); // bearing to landmark + buf.readUnsignedIntLE(); // distance to landmark + + position.setFixTime(new Date(buf.readUnsignedIntLE() * 1000)); + + buf.readUnsignedByte(); // reserved + break; + case 1: + buf.skipBytes(buf.readUnsignedShortLE()); // landmark + break; + case 4: + buf.skipBytes(53); // trip + break; + case 20: + buf.skipBytes(32); // extended + break; + case 22: + buf.readUnsignedByte(); // zone flag + buf.skipBytes(buf.readUnsignedShortLE()); // zone name + break; + case 30: + buf.skipBytes(79); // system status + break; + case 40: + buf.skipBytes(40); // analog + break; + case 50: + buf.skipBytes(buf.readUnsignedShortLE()); // console + break; + case 255: + buf.skipBytes(4); // acknowledgement + break; + default: + throw new IllegalArgumentException(String.format("Unknown type %d", type)); + } + } + + return position.getValid() ? position : null; + + } + private Position decode80(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws ParseException { buf.readUnsignedByte(); // version id @@ -135,15 +217,14 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { long id = buf.readUnsignedInt(); buf.readUnsignedInt(); // time - Position position = new Position(getProtocolName()); - position.set(Position.KEY_INDEX, index); - position.setValid(true); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_INDEX, index); if (channel != null) { channel.writeAndFlush(new NetworkMessage( @@ -159,6 +240,7 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { } position.setLatitude(Double.parseDouble(matcher.group(1))); position.setLongitude(Double.parseDouble(matcher.group(2))); + position.setValid(true); pattern = Pattern.compile("([NSWE]{1,2}) with speed (\\d+) km/h"); matcher = pattern.matcher(sentence); diff --git a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java index db3c5c32f..fdef8ce19 100644 --- a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java @@ -10,8 +10,8 @@ public class TramigoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TramigoProtocolDecoder(null)); - verifyNull(decoder, binary( - "0480001df35b1b69101a023ef34f0090436d38003200380e0000850081c0e4ff6d542f00000015000000050000000000007600a20100008f436d3800014400000000000000000021000a0006005a574a6169726f7320486972692043656e747265205072696d617279205363686f6f6c536f7574686572746f6e486172617265")); + /*verifyNull(decoder, binary( + "0480001df35b1b69101a023ef34f0090436d38003200380e0000850081c0e4ff6d542f00000015000000050000000000007600a20100008f436d3800014400000000000000000021000a0006005a574a6169726f7320486972692043656e747265205072696d617279205363686f6f6c536f7574686572746f6e486172617265"));*/ verifyAttributes(decoder, binary( "8000c426b000a6000101c557037598050d5c8a595472616d69676f3a204d6f76696e672c20302e3132206b6d2045206f66204c617275742054696e2049736c616d6963205072696d617279205363686f6f6c2c2054616970696e672c20506572616b2c204d592c20342e38333134392c203130302e37333038352c204e572077697468207370656564203130206b6d2f682c2030303a34393a30382041756720392020454f46")); -- cgit v1.2.3 From 02d073d6900c401f83493380df3093d72f4d5cf2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Feb 2023 14:27:47 -0800 Subject: Improve security filter --- .../traccar/api/security/SecurityRequestFilter.java | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index 94b6bbf05..9992d49e7 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -42,13 +42,6 @@ public class SecurityRequestFilter implements ContainerRequestFilter { private static final Logger LOGGER = LoggerFactory.getLogger(SecurityRequestFilter.class); - public static final String AUTHORIZATION_HEADER = "Authorization"; - public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; - public static final String BASIC_REALM = "Basic realm=\"api\""; - public static final String BEARER_PREFIX = "Bearer "; - public static final String X_REQUESTED_WITH = "X-Requested-With"; - public static final String XML_HTTP_REQUEST = "XMLHttpRequest"; - public static String[] decodeBasicAuth(String auth) { auth = auth.replaceFirst("[B|b]asic ", ""); byte[] decodedBytes = DataConverter.parseBase64(auth); @@ -81,13 +74,13 @@ public class SecurityRequestFilter implements ContainerRequestFilter { try { - String authHeader = requestContext.getHeaderString(AUTHORIZATION_HEADER); + String authHeader = requestContext.getHeaderString("Authorization"); if (authHeader != null) { try { User user; - if (authHeader.startsWith(BEARER_PREFIX)) { - user = loginService.login(authHeader.substring(BEARER_PREFIX.length())); + if (authHeader.startsWith("Bearer ")) { + user = loginService.login(authHeader.substring(7)); } else { String[] auth = decodeBasicAuth(authHeader); user = loginService.login(auth[0], auth[1]); @@ -120,8 +113,9 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Method method = resourceInfo.getResourceMethod(); if (!method.isAnnotationPresent(PermitAll.class)) { Response.ResponseBuilder responseBuilder = Response.status(Response.Status.UNAUTHORIZED); - if (!XML_HTTP_REQUEST.equals(request.getHeader(X_REQUESTED_WITH))) { - responseBuilder.header(WWW_AUTHENTICATE, BASIC_REALM); + String accept = request.getHeader("Accept"); + if (accept != null && accept.contains("text/html")) { + responseBuilder.header("WWW-Authenticate", "Basic realm=\"api\""); } throw new WebApplicationException(responseBuilder.build()); } -- cgit v1.2.3 From 33af2928a581eba6a1ba580b5da051612c7b7860 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Feb 2023 17:20:39 -0800 Subject: Meitrack K211G extend support --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 12 +++++++++++- .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 343141dca..a7accf0f1 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -510,6 +510,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x0D: position.set("runtime", buf.readUnsignedIntLE()); break; + case 0x25: + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE())); + break; case 0xA0: position.set(Position.KEY_FUEL_USED, buf.readUnsignedIntLE() * 0.001); break; @@ -624,6 +627,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { photo = Unpooled.buffer(); requestPhotoPacket(channel, remoteAddress, imei, "camera_picture.jpg", 0); return null; + case "D82": + Position position = new Position(getProtocolName()); + position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId()); + getLastLocation(position, null); + String result = buf.toString(index + 1, buf.writerIndex() - index - 4, StandardCharsets.US_ASCII); + position.set(Position.KEY_RESULT, result); + return position; case "CCC": return decodeBinaryC(channel, remoteAddress, buf); case "CCE": diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index ce0a1e922..407d7a9b6 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,13 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "$$u28,864606044993987,D82,0*D6"), + Position.KEY_RESULT, "D82,0"); + + verifyPositions(decoder, binary( + "24245B3139312C3836343630363034343939333938372C4343452C010000000200500013000601250500060007111B00470206080000093E000AE7030B0000199E011A850306028D7A570103F35ACC0604F9D06C2B0CB92E00000D3FA40C00250CA2B900010E0CCC010000B6276313000000004B00120006012A0500060007111B00470206080000093E000AE7030B0000199E011A7C0305028D7A570103F35ACC0604F9D06C2B0CB92E00000D3FA40C00010E0CCC010000B6276313000000002A31340D0A")); + verifyPositions(decoder, binary( "24246a3138312c3836343238313034313930383330332c4343452c00000000010093001f000505000600070714001502090800000900000a00000b0000160a001706001904001ad90440230006023279570103305ccc0604f536492b0c510300000d495701001c014000000b0e0ccc010000922781abb90c00002a030034212b03008b082c030053082d03009e082e030034212f030034213003003421310300342149090400000000000000004b07010104574946492a36310d0a")); -- cgit v1.2.3 From 782fd787d14bd041c818e25b06f5ebe844854163 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Feb 2023 09:08:14 -0800 Subject: Tramigo T24 M2MV2 support --- src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java | 8 ++++---- .../java/org/traccar/protocol/TramigoProtocolDecoderTest.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index 1296929bc..ddd669b36 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -153,8 +153,8 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, status); position.setValid(true); - position.setLatitude(buf.readInt() * 0.00001); - position.setLongitude(buf.readInt() * 0.00001); + position.setLatitude(buf.readIntLE() * 0.00001); + position.setLongitude(buf.readIntLE() * 0.00001); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); position.setCourse(buf.readUnsignedShortLE()); @@ -172,7 +172,7 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // reserved break; case 1: - buf.skipBytes(buf.readUnsignedShortLE()); // landmark + buf.skipBytes(buf.readUnsignedShortLE() - 3); // landmark break; case 4: buf.skipBytes(53); // trip @@ -191,7 +191,7 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(40); // analog break; case 50: - buf.skipBytes(buf.readUnsignedShortLE()); // console + buf.skipBytes(buf.readUnsignedShortLE() - 3); // console break; case 255: buf.skipBytes(4); // acknowledgement diff --git a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java index fdef8ce19..d692a41d5 100644 --- a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java @@ -10,8 +10,8 @@ public class TramigoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TramigoProtocolDecoder(null)); - /*verifyNull(decoder, binary( - "0480001df35b1b69101a023ef34f0090436d38003200380e0000850081c0e4ff6d542f00000015000000050000000000007600a20100008f436d3800014400000000000000000021000a0006005a574a6169726f7320486972692043656e747265205072696d617279205363686f6f6c536f7574686572746f6e486172617265"));*/ + verifyPosition(decoder, binary( + "0480001df35b1b69101a023ef34f0090436d38003200380e0000850081c0e4ff6d542f00000015000000050000000000007600a20100008f436d3800014400000000000000000021000a0006005a574a6169726f7320486972692043656e747265205072696d617279205363686f6f6c536f7574686572746f6e486172617265")); verifyAttributes(decoder, binary( "8000c426b000a6000101c557037598050d5c8a595472616d69676f3a204d6f76696e672c20302e3132206b6d2045206f66204c617275742054696e2049736c616d6963205072696d617279205363686f6f6c2c2054616970696e672c20506572616b2c204d592c20342e38333134392c203130302e37333038352c204e572077697468207370656564203130206b6d2f682c2030303a34393a30382041756720392020454f46")); -- cgit v1.2.3 From 9ceecf357132989390e8bb18160338b27539eaaa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Feb 2023 15:11:07 -0800 Subject: Refactor Totem decoder --- .../org/traccar/protocol/TotemProtocolDecoder.java | 123 +++++++++++++-------- 1 file changed, 77 insertions(+), 46 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 9d0d794f8..fc3dce86f 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -135,7 +135,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN4 = new PatternBuilder() .text("$$") // header .number("dddd") // length - .number("(xx)") // type + .number("xx") // type .number("(d+)|") // imei .number("(x{8})") // status .number("(dd)(dd)(dd)") // date (yymmdd) @@ -257,7 +257,20 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { } } - private boolean decode12(Position position, Parser parser, Pattern pattern) { + private Position decode12(Channel channel, SocketAddress remoteAddress, String sentence, Pattern pattern) { + + Parser parser = new Parser(pattern, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); if (parser.hasNext()) { position.set(Position.KEY_ALARM, decodeAlarm123(Short.parseShort(parser.next(), 16))); @@ -283,7 +296,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { year = parser.nextInt(0); } if (year == 0) { - return false; // ignore invalid data + return null; // ignore invalid data } dateBuilder.setDate(year, month, day); position.setTime(dateBuilder.getDate()); @@ -331,10 +344,23 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, parser.next()); position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - return true; + return position; } - private boolean decode3(Position position, Parser parser) { + private Position decode3(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN3, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); if (parser.hasNext()) { position.set(Position.KEY_ALARM, decodeAlarm123(Short.parseShort(parser.next(), 16))); @@ -363,10 +389,27 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); - return true; + return position; } - private boolean decode4(Position position, Parser parser) { + private Position decode4(Channel channel, SocketAddress remoteAddress, String sentence) { + + int type = Integer.parseInt(sentence.substring(6, 8), 16); + + Parser parser = new Parser(PATTERN4, sentence); + if (!parser.matches()) { + return null; + } + + 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, decodeAlarm4(type)); long status = parser.nextHexLong(); @@ -427,10 +470,23 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); - return true; + return position; } - private boolean decodeObd(Position position, Parser parser) { + private Position decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_OBD, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); position.setValid(true); position.setTime(parser.nextDateTime()); @@ -451,7 +507,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_THROTTLE, parser.nextInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - return true; + return position; } @Override @@ -459,50 +515,25 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - Pattern pattern = PATTERN3; + + Position position; if (sentence.contains("$Cloud")) { - pattern = PATTERN_OBD; + position = decodeObd(channel, remoteAddress, sentence); } else if (sentence.charAt(2) == '0') { - pattern = PATTERN4; + position = decode4(channel, remoteAddress, sentence); } else if (sentence.contains("$GPRMC")) { - pattern = PATTERN1; + position = decode12(channel, remoteAddress, sentence, PATTERN1); } else { int index = sentence.indexOf('|'); if (index != -1 && sentence.indexOf('|', index + 1) != -1) { - pattern = PATTERN2; + position = decode12(channel, remoteAddress, sentence, PATTERN2); + } else { + position = decode3(channel, remoteAddress, sentence); } } - Parser parser = new Parser(pattern, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - if (pattern == PATTERN4) { - position.set(Position.KEY_ALARM, decodeAlarm4(parser.nextHexInt())); - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - boolean result; - if (pattern == PATTERN1 || pattern == PATTERN2) { - result = decode12(position, parser, pattern); - } else if (pattern == PATTERN3) { - result = decode3(position, parser); - } else if (pattern == PATTERN4) { - result = decode4(position, parser); - } else { - result = decodeObd(position, parser); - } - if (channel != null) { - if (pattern == PATTERN4) { + if (sentence.charAt(2) == '0') { String response = "$$0014AA" + sentence.substring(sentence.length() - 6, sentence.length() - 2); response += String.format("%02X", Checksum.xor(response)).toUpperCase(); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); @@ -511,7 +542,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { } } - return result ? position : null; + return position; } } -- cgit v1.2.3 From a722658e5a3c2c15ceffa51a80b63bda758264bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Feb 2023 15:18:44 -0800 Subject: Decode AT07 RFID data --- .../org/traccar/protocol/TotemProtocolDecoder.java | 58 +++++++++++++++++++--- .../traccar/protocol/TotemProtocolDecoderTest.java | 5 ++ 2 files changed, 57 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index fc3dce86f..6f039c324 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -176,7 +176,21 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); - private static final Pattern PATTERN_OBD = new PatternBuilder() + private static final Pattern PATTERN_E2 = new PatternBuilder() + .text("$$") // header + .number("dddd") // length + .number("xx") // type + .number("(d+)|") // imei + .number("(dd)(dd)(dd)") // date (yymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(-?d+.d+),") // longitude + .number("(-?d+.d+),") // latitude + .expression("(.+)") // rfid + .number("|xx") // checksum + .any() + .compile(); + + private static final Pattern PATTERN_E5 = new PatternBuilder() .text("$$") // header .number("dddd") // length .number("xx") // type @@ -396,6 +410,15 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { int type = Integer.parseInt(sentence.substring(6, 8), 16); + switch (type) { + case 0xE2: + return decodeE2(channel, remoteAddress, sentence); + case 0xE5: + return decodeE5(channel, remoteAddress, sentence); + default: + break; + } + Parser parser = new Parser(PATTERN4, sentence); if (!parser.matches()) { return null; @@ -473,9 +496,34 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { return position; } - private Position decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { + private Position decodeE2(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_E2, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(parser.nextDateTime()); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + + return position; + } + + private Position decodeE5(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_OBD, sentence); + Parser parser = new Parser(PATTERN_E5, sentence); if (!parser.matches()) { return null; } @@ -517,9 +565,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { String sentence = (String) msg; Position position; - if (sentence.contains("$Cloud")) { - position = decodeObd(channel, remoteAddress, sentence); - } else if (sentence.charAt(2) == '0') { + if (sentence.charAt(2) == '0') { position = decode4(channel, remoteAddress, sentence); } else if (sentence.contains("$GPRMC")) { position = decode12(channel, remoteAddress, sentence, PATTERN1); diff --git a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java index df5734568..1e432bd9e 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class TotemProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,10 @@ public class TotemProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TotemProtocolDecoder(null)); + verifyAttribute(decoder, text( + "$$0494E2123456789012345|150425223945,113.925525,22.55814,1122334455|38"), + Position.KEY_DRIVER_UNIQUE_ID, "1122334455"); + verifyPosition(decoder, text( "$$0111AA353081090067318|0804400022070722520240400005B364ED5003107300001.700000002245.3919N10231.6952W000001860E")); -- cgit v1.2.3 From ec2b7b64a83aa1c3dcd0cd69c1ae7b2d0d8a7864 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 17 Feb 2023 08:16:37 -0800 Subject: Support GL600 frames --- src/main/java/org/traccar/protocol/Jt600FrameDecoder.java | 2 +- src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java | 8 ++++---- src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java | 8 ++++++++ 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java b/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java index bfefb94a7..f7890f814 100644 --- a/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java @@ -35,7 +35,7 @@ public class Jt600FrameDecoder extends BaseFrameDecoder { char type = (char) buf.getByte(buf.readerIndex()); if (type == '$') { - boolean longFormat = Jt600ProtocolDecoder.isLongFormat(buf, buf.readerIndex() + 1); + boolean longFormat = Jt600ProtocolDecoder.isLongFormat(buf); int length = buf.getUnsignedShort(buf.readerIndex() + (longFormat ? 8 : 7)) + 10; if (length <= buf.readableBytes()) { return buf.readRetainedSlice(length); diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 9ed44f565..dc763dea7 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -86,8 +86,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { } - static boolean isLongFormat(ByteBuf buf, int flagIndex) { - return buf.getUnsignedByte(flagIndex) >> 4 >= 7; + static boolean isLongFormat(ByteBuf buf) { + return buf.getUnsignedByte(buf.readerIndex() + 8) == 0; } static void decodeBinaryLocation(ByteBuf buf, Position position) { @@ -123,9 +123,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { List positions = new LinkedList<>(); - buf.readByte(); // header + boolean longFormat = isLongFormat(buf); - boolean longFormat = isLongFormat(buf, buf.readerIndex()); + buf.readByte(); // header String id = String.valueOf(Long.parseLong(ByteBufUtil.hexDump(buf.readSlice(5)))); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); diff --git a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java index 8e408e50f..895a0b07b 100644 --- a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java @@ -10,6 +10,14 @@ public class Jt600FrameDecoderTest extends ProtocolTest { var decoder = inject(new Jt600FrameDecoder()); + verifyFrame( + binary("2460201102320112003401010000000422434199114158229e000000000009000000000010e06400000000000020100e0868817043592664000000000000"), + decoder.decode(null, null, binary("2460201102320112003401010000000422434199114158229e000000000009000000000010e06400000000000020100e0868817043592664000000000000"))); + + verifyFrame( + binary("24657060730131001b13111710361906538525079524797f000000000000000003f300036c"), + decoder.decode(null, null, binary("24657060730131001b13111710361906538525079524797f000000000000000003f300036c"))); + verifyFrame( binary("2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e"), decoder.decode(null, null, binary("2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e"))); -- cgit v1.2.3 From 8ae0436e5edb76243e59ee6e9b2c1a6132fd9464 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Feb 2023 13:56:32 -0800 Subject: Fix Queclink GL53MG decoding --- src/main/java/org/traccar/helper/Parser.java | 11 +++++++++++ .../java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java | 2 +- .../java/org/traccar/protocol/StartekProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/WialonProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 6 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/Parser.java b/src/main/java/org/traccar/helper/Parser.java index aa39e1ad7..c2aea28fa 100644 --- a/src/main/java/org/traccar/helper/Parser.java +++ b/src/main/java/org/traccar/helper/Parser.java @@ -48,6 +48,17 @@ public class Parser { } public boolean hasNext(int number) { + for (int i = position; i < position + number; i++) { + String value = matcher.group(i); + if (value == null || value.isEmpty()) { + position += number; + return false; + } + } + return true; + } + + public boolean hasNextAny(int number) { for (int i = position; i < position + number; i++) { String value = matcher.group(i); if (value != null && !value.isEmpty()) { diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 517499f02..28308ab77 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -956,7 +956,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, power * 0.001); } - if (parser.hasNext(12)) { + if (parser.hasNextAny(12)) { position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_HOURS, parseHours(parser.next())); diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index 28efa3c30..d1c35b478 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -225,7 +225,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); } - if (parser.hasNext(20)) { + if (parser.hasNextAny(20)) { String utcHours = parser.next(); String utcMinutes = parser.next(); diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 8e3624cb5..d75da7fbd 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -221,7 +221,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } } - if (parser.hasNext(6)) { + if (parser.hasNextAny(6)) { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); position.set("airFlow", parser.nextInt()); diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 3d57525b7..b87ba2b53 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -101,7 +101,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { position.setTime(new Date()); } - if (parser.hasNext(9)) { + if (parser.hasNextAny(9)) { position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index f3a77228c..5696353c4 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyPositions(decoder, false, buffer( + "+BUFF:GTFRI,2E0503,861106050005423,,,0,1,,,,,,,,,,,,0,0,,98,1,0,,,20200101000001,0083$")); + verifyAttribute(decoder, buffer( "+RESP:GTERI,271002,863457051562823,,00000002,,10,1,1,0.0,15,28.2,-58.695253,-34.625413,20230119193305,0722,0007,1168,16B3BB,00,0.0,,,,99,210100,2,1,28F8A149F69A3C25,1,0190,20230119193314,07C7$"), Position.PREFIX_TEMP + 1, 25.0); -- 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 'src/main/java/org') 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 cd1d80896b16c84ae0a8a4631a9dba6955e9e344 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Feb 2023 14:33:36 -0800 Subject: Implement command notificator --- schema/changelog-5.7.xml | 25 +++++++++ schema/changelog-master.xml | 1 + .../traccar/api/resource/NotificationResource.java | 6 +-- .../traccar/api/security/PermissionsService.java | 20 +++++-- src/main/java/org/traccar/model/Notification.java | 12 ++++- .../traccar/notificators/NotificatorCommand.java | 62 ++++++++++++++++++++++ 6 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 schema/changelog-5.7.xml create mode 100644 src/main/java/org/traccar/notificators/NotificatorCommand.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.7.xml b/schema/changelog-5.7.xml new file mode 100644 index 000000000..ad15ac48c --- /dev/null +++ b/schema/changelog-5.7.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 0835918c9..1587cc789 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -37,5 +37,6 @@ + diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index d58557601..7005fc083 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 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. @@ -80,7 +80,7 @@ public class NotificationResource extends ExtendedObjectResource { @POST @Path("test") - public Response testMessage() throws MessageException, InterruptedException, StorageException { + public Response testMessage() throws MessageException, StorageException { User user = permissionsService.getUser(getUserId()); for (Typed method : notificatorManager.getAllNotificatorTypes()) { notificatorManager.getNotificator(method.getType()).send(null, user, new Event("test", 0), null); @@ -91,7 +91,7 @@ public class NotificationResource extends ExtendedObjectResource { @POST @Path("test/{notificator}") public Response testMessage(@PathParam("notificator") String notificator) - throws MessageException, InterruptedException, StorageException { + throws MessageException, StorageException { User user = permissionsService.getUser(getUserId()); notificatorManager.getNotificator(notificator).send(null, user, new Event("test", 0), null); return Response.noContent().build(); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 4421572d7..18a376601 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -23,6 +23,7 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.GroupedModel; import org.traccar.model.ManagedUser; +import org.traccar.model.Notification; import org.traccar.model.ScheduledModel; import org.traccar.model.Server; import org.traccar.model.User; @@ -129,7 +130,7 @@ public class PermissionsService { GroupedModel before = null; if (!addition) { before = storage.getObject(after.getClass(), new Request( - new Columns.Include("groupId"), new Condition.Equals("id", object.getId()))); + new Columns.Include("groupId"), new Condition.Equals("id", after.getId()))); } if (before == null || before.getGroupId() != after.getGroupId()) { checkPermission(Group.class, userId, after.getGroupId()); @@ -142,13 +143,26 @@ public class PermissionsService { ScheduledModel before = null; if (!addition) { before = storage.getObject(after.getClass(), new Request( - new Columns.Include("calendarId"), new Condition.Equals("id", object.getId()))); + new Columns.Include("calendarId"), new Condition.Equals("id", after.getId()))); } if (before == null || before.getCalendarId() != after.getCalendarId()) { checkPermission(Calendar.class, userId, after.getCalendarId()); } } } + if (object instanceof Notification) { + Notification after = ((Notification) object); + if (after.getCommandId() > 0) { + Notification before = null; + if (!addition) { + before = storage.getObject(after.getClass(), new Request( + new Columns.Include("commandId"), new Condition.Equals("id", after.getId()))); + } + if (before == null || before.getCommandId() != after.getCommandId()) { + checkPermission(Command.class, userId, after.getCommandId()); + } + } + } } } diff --git a/src/main/java/org/traccar/model/Notification.java b/src/main/java/org/traccar/model/Notification.java index 95e446132..b6a6e4cf5 100644 --- a/src/main/java/org/traccar/model/Notification.java +++ b/src/main/java/org/traccar/model/Notification.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 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. @@ -46,6 +46,16 @@ public class Notification extends ScheduledModel { this.type = type; } + private long commandId; + + public long getCommandId() { + return commandId; + } + + public void setCommandId(long commandId) { + this.commandId = commandId; + } + private String notificators; public String getNotificators() { diff --git a/src/main/java/org/traccar/notificators/NotificatorCommand.java b/src/main/java/org/traccar/notificators/NotificatorCommand.java new file mode 100644 index 000000000..55cbe0a6a --- /dev/null +++ b/src/main/java/org/traccar/notificators/NotificatorCommand.java @@ -0,0 +1,62 @@ +/* + * 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.notificators; + +import org.traccar.database.CommandsManager; +import org.traccar.model.Command; +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; +import org.traccar.storage.Storage; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class NotificatorCommand implements Notificator { + + private final Storage storage; + private final CommandsManager commandsManager; + + @Inject + public NotificatorCommand(Storage storage, CommandsManager commandsManager) { + this.storage = storage; + this.commandsManager = commandsManager; + } + + @Override + public void send(Notification notification, User user, Event event, Position position) throws MessageException { + + if (notification == null || notification.getCommandId() <= 0) { + throw new MessageException("Saved command not provided"); + } + + try { + Command command = storage.getObject(Command.class, new Request( + new Columns.All(), new Condition.Equals("id", notification.getCommandId()))); + command.setDeviceId(event.getDeviceId()); + commandsManager.sendCommand(command); + } catch (Exception e) { + throw new MessageException(e); + } + } + +} -- cgit v1.2.3 From 754ff3a85baf2faaa1b962f16f52ebd0e12e6436 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 21 Feb 2023 09:52:22 -0800 Subject: Add lock attribute --- src/main/java/org/traccar/model/Position.java | 1 + src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 1286db5f2..41cfeaf2e 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -83,6 +83,7 @@ public class Position extends Message { public static final String KEY_OPERATOR = "operator"; public static final String KEY_COMMAND = "command"; public static final String KEY_BLOCKED = "blocked"; + public static final String KEY_LOCK = "lock"; public static final String KEY_DOOR = "door"; public static final String KEY_AXLE_WEIGHT = "axleWeight"; public static final String KEY_G_SENSOR = "gSensor"; diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index 313210f63..423ae3ffe 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -63,7 +63,7 @@ public class TeraTrackProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(json.getString("Speed")))); position.set(Position.KEY_ODOMETER, Integer.parseInt(json.getString("Mileage"))); - position.set(Position.KEY_BLOCKED, json.getString("LockOpen").equals("0")); + position.set(Position.KEY_LOCK, json.getString("LockOpen").equals("0")); position.set(Position.KEY_DRIVER_UNIQUE_ID, json.getString("CardNo")); position.set(Position.KEY_ALARM, json.getString("LowPower").equals("1") ? Position.ALARM_LOW_POWER : null); position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(json.getString("Power"))); -- cgit v1.2.3 From 392f00082faff72c9948ed569e4c883a5fabe7d6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 21 Feb 2023 09:56:03 -0800 Subject: Support Meitrack K211G lock --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 6 ++++++ src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index a7accf0f1..5c5ba4be4 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -420,6 +420,12 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x15: position.set(Position.KEY_INPUT, buf.readUnsignedByte()); break; + case 0x47: + int lockState = buf.readUnsignedByte(); + if (lockState > 0) { + position.set(Position.KEY_LOCK, lockState == 2); + } + break; case 0x97: position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); break; diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 407d7a9b6..419eddf63 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "24245b3131342c3836343630363034343939333938372c4343452c0000000001005000130006012305000600070f1b004702060800000900000a00000b0000199d011a00000602d179570103b25ccc0604cf04862b0cc65b01000da4090d001c01000000010e0ccc010000b627be11000000002a41300d0a"), + Position.KEY_LOCK, true); + verifyAttribute(decoder, buffer( "$$u28,864606044993987,D82,0*D6"), Position.KEY_RESULT, "D82,0"); -- cgit v1.2.3 From 7678392d85f43c60c93f2a08dcba6aa7ec6102e4 Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Tue, 21 Feb 2023 22:39:14 +0300 Subject: Implement JEXL parser settings --- src/main/java/org/traccar/config/Keys.java | 95 ++++++++++++++++++++++ .../traccar/handler/ComputedAttributesHandler.java | 43 +++++++++- 2 files changed, 134 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 093f4298c..49af7cfab 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1299,6 +1299,101 @@ public final class Keys { public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new BooleanConfigKey( "processing.computedAttributes.deviceAttributes", List.of(KeyType.CONFIG)); + /** + * Enable annotation constructs processing. + * When disabled, parsing a script/expression using syntactic annotation constructs (@annotation) will throw a parsing exception. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_ANNOTATION = new BooleanConfigKey( + "processing.computedAttributes.parser.annotation", + List.of(KeyType.CONFIG)); + /** + * Enable array references processing. + * When disabled, parsing a script/expression using 'obj[ ref ]' where ref is not a string or integer literal will throw a parsing exception; + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_ARRAY_REFERENCES = new BooleanConfigKey( + "processing.computedAttributes.parser.arrayReferences", + List.of(KeyType.CONFIG)); + /** + * Enable lambda declaration. + * When disabled, parsing a script/expression using syntactic lambda constructs (->,function) will throw a parsing exception. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LAMBDA = new BooleanConfigKey( + "processing.computedAttributes.parser.lambda", + List.of(KeyType.CONFIG)); + /** + * Enable whether redefining local variables is an error. + * When disabled, parsing a script/expression using a local variable or parameter syntax will throw a parsing exception. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL = new BooleanConfigKey( + "processing.computedAttributes.parser.lexical", + List.of(KeyType.CONFIG)); + /** + * Enable whether local variables shade global variables outside their scope. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL_SHADE = new BooleanConfigKey( + "processing.computedAttributes.parser.lexicalShade", + List.of(KeyType.CONFIG)); + /** + * Enable local variables declaration. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES = new BooleanConfigKey( + "processing.computedAttributes.parser.localVariables", + List.of(KeyType.CONFIG)); + /** + * Enable loops processing. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOOPS = new BooleanConfigKey( + "processing.computedAttributes.parser.loops", + List.of(KeyType.CONFIG)); + /** + * Set whether object method calls are enabled. + * When disabled, parsing a script/expression using 'obj.method()' will throw a parsing exception; + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_METHOD_CALLS = new BooleanConfigKey( + "processing.computedAttributes.parser.method_calls", + List.of(KeyType.CONFIG)); + /** + * Enable new instances creation. + * When disabled, parsing a script/expression using 'new(...)' will throw a parsing exception; using a class as functor will fail. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION = new BooleanConfigKey( + "processing.computedAttributes.parser.newInstanceCreation", + List.of(KeyType.CONFIG)); + /** + * Enable pragma expressions processing. + * When disabled, parsing a script/expression using syntactic pragma constructs (#pragma) will throw a parsing exception. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_PRAGMA = new BooleanConfigKey( + "processing.computedAttributes.parser.pragma", + List.of(KeyType.CONFIG)); + /** + * Enable scripts constructs processing. + * When disabled, parsing a script using syntactic script constructs (statements, ...) will throw a parsing exception. + * Dangerous, as can be used to escalate privileges on the Traccar server. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_SCRIPT_CONSTRUCTS = new BooleanConfigKey( + "processing.computedAttributes.parser.scriptConstructs", + List.of(KeyType.CONFIG)); + /** + * Enable side effect expressions processing. + * When disabled, parsing a script/expression using syntactical constructs modifying variables or members will throw a parsing exception. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT = new BooleanConfigKey( + "processing.computedAttributes.parser.sideEffect", + List.of(KeyType.CONFIG)); + /** + * Set whether side effect expressions on global variables (aka non-local) are enabled. + * When disabled, parsing a script/expression using syntactical constructs modifying variables including all potentially ant-ish variables will throw a parsing exception. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT_GLOBAL = new BooleanConfigKey( + "processing.computedAttributes.parser.sideEffectGlobal", + List.of(KeyType.CONFIG)); + /** + * Enable array/map/set literal expressions processing. + */ + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_STRUCTURED_LITERAL = new BooleanConfigKey( + "processing.computedAttributes.parser.structuredLiteral", + List.of(KeyType.CONFIG)); /** * Boolean flag to enable or disable reverse geocoder. diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index ca6c0fc74..c3f202fa2 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -26,10 +26,8 @@ import java.util.Map; import java.util.Set; import io.netty.channel.ChannelHandler; -import org.apache.commons.jexl3.JexlBuilder; -import org.apache.commons.jexl3.JexlEngine; -import org.apache.commons.jexl3.JexlException; -import org.apache.commons.jexl3.MapContext; +import org.apache.commons.jexl3.*; +import org.apache.commons.jexl3.introspection.JexlSandbox; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; @@ -55,14 +53,51 @@ public class ComputedAttributesHandler extends BaseDataHandler { private final boolean includeDeviceAttributes; + @Inject public ComputedAttributesHandler(Config config, CacheManager cacheManager) { this.cacheManager = cacheManager; + boolean enableJEXLAnnotation = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_ANNOTATION); + boolean enableJEXLArrayReferences = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_ARRAY_REFERENCES); + boolean enableJEXLLambdas = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LAMBDA); + boolean enableJEXLLexical = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL); + boolean enableJEXLLexicalShade = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL_SHADE); + boolean enableJEXLLocalVariables = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES); + boolean enableJEXLLoops = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS); + boolean enableJEXLMethodCalls = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_METHOD_CALLS); + boolean enableJEXLNewInstanceCreation = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION); + boolean enableJEXLPragma = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_PRAGMA); + boolean enableJEXLScriptConstructs = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_SCRIPT_CONSTRUCTS); + boolean enableJEXLSideEffect = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT); + boolean enableJEXLSideEffectGlobal = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT_GLOBAL); + boolean enableJEXLStructuredLiteral = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_STRUCTURED_LITERAL); + JexlSandbox sandbox = new JexlSandbox(false); + sandbox.allow("com.safe.Functions"); + boolean enableJEXLRegister = true; + JexlFeatures features = new JexlFeatures() + .annotation(enableJEXLAnnotation) + .arrayReferenceExpr(enableJEXLArrayReferences) + .lambda(enableJEXLLambdas) + .lexical(enableJEXLLexical) + .lexicalShade(enableJEXLLexicalShade) + .localVar(enableJEXLLocalVariables) + .loops(enableJEXLLoops) + .methodCall(enableJEXLMethodCalls) + .newInstance(enableJEXLNewInstanceCreation) + .pragma(enableJEXLPragma) + .register(enableJEXLRegister) + .script(enableJEXLScriptConstructs) + .sideEffect(enableJEXLSideEffect) + .sideEffectGlobal(enableJEXLSideEffectGlobal) + .structuredLiteral(enableJEXLStructuredLiteral); engine = new JexlBuilder() .strict(true) .namespaces(Collections.singletonMap("math", Math.class)) + .sandbox(sandbox) + .features(features) .create(); includeDeviceAttributes = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES); + } private MapContext prepareContext(Position position) { -- cgit v1.2.3 From a41ad7237035b27634cd6eac1a68e3cf1b553be9 Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Tue, 21 Feb 2023 23:14:35 +0300 Subject: Shorten JEXL features palette --- src/main/java/org/traccar/config/Keys.java | 83 +--------------------- .../traccar/handler/ComputedAttributesHandler.java | 25 +------ 2 files changed, 4 insertions(+), 104 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 49af7cfab..53f0336cc 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1299,102 +1299,25 @@ public final class Keys { public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new BooleanConfigKey( "processing.computedAttributes.deviceAttributes", List.of(KeyType.CONFIG)); - /** - * Enable annotation constructs processing. - * When disabled, parsing a script/expression using syntactic annotation constructs (@annotation) will throw a parsing exception. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_ANNOTATION = new BooleanConfigKey( - "processing.computedAttributes.parser.annotation", - List.of(KeyType.CONFIG)); - /** - * Enable array references processing. - * When disabled, parsing a script/expression using 'obj[ ref ]' where ref is not a string or integer literal will throw a parsing exception; - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_ARRAY_REFERENCES = new BooleanConfigKey( - "processing.computedAttributes.parser.arrayReferences", - List.of(KeyType.CONFIG)); - /** - * Enable lambda declaration. - * When disabled, parsing a script/expression using syntactic lambda constructs (->,function) will throw a parsing exception. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LAMBDA = new BooleanConfigKey( - "processing.computedAttributes.parser.lambda", - List.of(KeyType.CONFIG)); - /** - * Enable whether redefining local variables is an error. - * When disabled, parsing a script/expression using a local variable or parameter syntax will throw a parsing exception. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL = new BooleanConfigKey( - "processing.computedAttributes.parser.lexical", - List.of(KeyType.CONFIG)); - /** - * Enable whether local variables shade global variables outside their scope. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL_SHADE = new BooleanConfigKey( - "processing.computedAttributes.parser.lexicalShade", - List.of(KeyType.CONFIG)); /** * Enable local variables declaration. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES = new BooleanConfigKey( - "processing.computedAttributes.parser.localVariables", + "processing.computedAttributes.localVariables", List.of(KeyType.CONFIG)); /** * Enable loops processing. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOOPS = new BooleanConfigKey( - "processing.computedAttributes.parser.loops", - List.of(KeyType.CONFIG)); - /** - * Set whether object method calls are enabled. - * When disabled, parsing a script/expression using 'obj.method()' will throw a parsing exception; - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_METHOD_CALLS = new BooleanConfigKey( - "processing.computedAttributes.parser.method_calls", + "processing.computedAttributes.loops", List.of(KeyType.CONFIG)); /** * Enable new instances creation. * When disabled, parsing a script/expression using 'new(...)' will throw a parsing exception; using a class as functor will fail. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION = new BooleanConfigKey( - "processing.computedAttributes.parser.newInstanceCreation", + "processing.computedAttributes.newInstanceCreation", List.of(KeyType.CONFIG)); - /** - * Enable pragma expressions processing. - * When disabled, parsing a script/expression using syntactic pragma constructs (#pragma) will throw a parsing exception. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_PRAGMA = new BooleanConfigKey( - "processing.computedAttributes.parser.pragma", - List.of(KeyType.CONFIG)); - /** - * Enable scripts constructs processing. - * When disabled, parsing a script using syntactic script constructs (statements, ...) will throw a parsing exception. - * Dangerous, as can be used to escalate privileges on the Traccar server. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_SCRIPT_CONSTRUCTS = new BooleanConfigKey( - "processing.computedAttributes.parser.scriptConstructs", - List.of(KeyType.CONFIG)); - /** - * Enable side effect expressions processing. - * When disabled, parsing a script/expression using syntactical constructs modifying variables or members will throw a parsing exception. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT = new BooleanConfigKey( - "processing.computedAttributes.parser.sideEffect", - List.of(KeyType.CONFIG)); - /** - * Set whether side effect expressions on global variables (aka non-local) are enabled. - * When disabled, parsing a script/expression using syntactical constructs modifying variables including all potentially ant-ish variables will throw a parsing exception. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT_GLOBAL = new BooleanConfigKey( - "processing.computedAttributes.parser.sideEffectGlobal", - List.of(KeyType.CONFIG)); - /** - * Enable array/map/set literal expressions processing. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_STRUCTURED_LITERAL = new BooleanConfigKey( - "processing.computedAttributes.parser.structuredLiteral", - List.of(KeyType.CONFIG)); - /** * Boolean flag to enable or disable reverse geocoder. */ diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index c3f202fa2..912665630 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -57,39 +57,16 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Inject public ComputedAttributesHandler(Config config, CacheManager cacheManager) { this.cacheManager = cacheManager; - boolean enableJEXLAnnotation = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_ANNOTATION); - boolean enableJEXLArrayReferences = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_ARRAY_REFERENCES); - boolean enableJEXLLambdas = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LAMBDA); - boolean enableJEXLLexical = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL); - boolean enableJEXLLexicalShade = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LEXICAL_SHADE); boolean enableJEXLLocalVariables = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES); boolean enableJEXLLoops = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS); - boolean enableJEXLMethodCalls = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_METHOD_CALLS); boolean enableJEXLNewInstanceCreation = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION); - boolean enableJEXLPragma = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_PRAGMA); - boolean enableJEXLScriptConstructs = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_SCRIPT_CONSTRUCTS); - boolean enableJEXLSideEffect = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT); - boolean enableJEXLSideEffectGlobal = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_SIDE_EFFECT_GLOBAL); - boolean enableJEXLStructuredLiteral = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_STRUCTURED_LITERAL); JexlSandbox sandbox = new JexlSandbox(false); sandbox.allow("com.safe.Functions"); - boolean enableJEXLRegister = true; JexlFeatures features = new JexlFeatures() - .annotation(enableJEXLAnnotation) - .arrayReferenceExpr(enableJEXLArrayReferences) - .lambda(enableJEXLLambdas) - .lexical(enableJEXLLexical) - .lexicalShade(enableJEXLLexicalShade) .localVar(enableJEXLLocalVariables) .loops(enableJEXLLoops) - .methodCall(enableJEXLMethodCalls) .newInstance(enableJEXLNewInstanceCreation) - .pragma(enableJEXLPragma) - .register(enableJEXLRegister) - .script(enableJEXLScriptConstructs) - .sideEffect(enableJEXLSideEffect) - .sideEffectGlobal(enableJEXLSideEffectGlobal) - .structuredLiteral(enableJEXLStructuredLiteral); + .structuredLiteral(true); engine = new JexlBuilder() .strict(true) .namespaces(Collections.singletonMap("math", Math.class)) -- cgit v1.2.3 From 99bbdac84d85ec57c9f7955ba353c86217e0dabc Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Tue, 21 Feb 2023 23:38:13 +0300 Subject: fix imports --- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 912665630..76f9c8f24 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -26,8 +26,12 @@ import java.util.Map; import java.util.Set; import io.netty.channel.ChannelHandler; -import org.apache.commons.jexl3.*; +import org.apache.commons.jexl3.JexlFeatures; +import org.apache.commons.jexl3.JexlEngine; +import org.apache.commons.jexl3.JexlBuilder; import org.apache.commons.jexl3.introspection.JexlSandbox; +import org.apache.commons.jexl3.JexlException; +import org.apache.commons.jexl3.MapContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; -- cgit v1.2.3 From 5bed640e8b87526a077d6a8411cddfac9c8661ae Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Wed, 22 Feb 2023 07:20:49 +0300 Subject: note comments --- .../java/org/traccar/handler/ComputedAttributesHandler.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 76f9c8f24..73b549195 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -57,19 +57,15 @@ public class ComputedAttributesHandler extends BaseDataHandler { private final boolean includeDeviceAttributes; - @Inject public ComputedAttributesHandler(Config config, CacheManager cacheManager) { this.cacheManager = cacheManager; - boolean enableJEXLLocalVariables = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES); - boolean enableJEXLLoops = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS); - boolean enableJEXLNewInstanceCreation = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION); JexlSandbox sandbox = new JexlSandbox(false); sandbox.allow("com.safe.Functions"); JexlFeatures features = new JexlFeatures() - .localVar(enableJEXLLocalVariables) - .loops(enableJEXLLoops) - .newInstance(enableJEXLNewInstanceCreation) + .localVar(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES)) + .loops(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS)) + .newInstance(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION)) .structuredLiteral(true); engine = new JexlBuilder() .strict(true) @@ -78,7 +74,6 @@ public class ComputedAttributesHandler extends BaseDataHandler { .features(features) .create(); includeDeviceAttributes = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES); - } private MapContext prepareContext(Position position) { -- cgit v1.2.3 From 51f0299aefe728163ac69f36cf9223c08ecd97aa Mon Sep 17 00:00:00 2001 From: Alexandre Truppel Date: Wed, 22 Feb 2023 14:27:07 +0100 Subject: Start writing boolean special case --- .../traccar/protocol/WialonProtocolDecoder.java | 60 ++++++++++++++-------- 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index b87ba2b53..1fc434ed8 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -39,31 +39,31 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN_ANY = new PatternBuilder() - .expression("([^#]+)?") // imei - .text("#") // start byte - .expression("([^#]+)") // type - .text("#") // separator - .expression("(.*)") // message + .expression("([^#]+)?") // imei + .text("#") // start byte + .expression("([^#]+)") // type + .text("#") // separator + .expression("(.*)") // message .compile(); private static final Pattern PATTERN = new PatternBuilder() - .number("(?:NA|(dd)(dd)(dd));") // date (ddmmyy) - .number("(?:NA|(dd)(dd)(dd));") // time (hhmmss) - .number("(?:NA|(dd)(dd.d+));") // latitude + .number("(?:NA|(dd)(dd)(dd));") // date (ddmmyy) + .number("(?:NA|(dd)(dd)(dd));") // time (hhmmss) + .number("(?:NA|(dd)(dd.d+));") // latitude .expression("(?:NA|([NS]));") - .number("(?:NA|(ddd)(dd.d+));") // longitude + .number("(?:NA|(ddd)(dd.d+));") // longitude .expression("(?:NA|([EW]));") - .number("(?:NA|(d+.?d*))?;") // speed - .number("(?:NA|(d+.?d*))?;") // course - .number("(?:NA|(-?d+.?d*));") // altitude - .number("(?:NA|(d+))") // satellites + .number("(?:NA|(d+.?d*))?;") // speed + .number("(?:NA|(d+.?d*))?;") // course + .number("(?:NA|(-?d+.?d*));") // altitude + .number("(?:NA|(d+))") // satellites .groupBegin().text(";") - .number("(?:NA|(d+.?d*));") // hdop - .number("(?:NA|(d+));") // inputs - .number("(?:NA|(d+));") // outputs - .expression("(?:NA|([^;]*));") // adc - .expression("(?:NA|([^;]*));") // ibutton - .expression("(?:NA|(.*))") // params + .number("(?:NA|(d+.?d*));") // hdop + .number("(?:NA|(d+));") // inputs + .number("(?:NA|(d+));") // outputs + .expression("(?:NA|([^;]*));") // adc + .expression("(?:NA|([^;]*));") // ibutton + .expression("(?:NA|(.*))") // params .groupEnd("?") .compile(); @@ -135,10 +135,28 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { for (String param : values) { Matcher paramParser = Pattern.compile("(.*):[1-3]:(.*)").matcher(param); if (paramParser.matches()) { + // Parsing gives a (string,string) key-value pair + String key = paramParser.group(1).toLowerCase(); + String value = paramParser.group(2); + + // Key is already in correct type (string) + // If we can parse the value as a double, then we use that as the value's type + // If not, value type is a string unless it is equal to some specific cases (true, yes, etc), in which case we convert into a boolean + try { - position.set(paramParser.group(1).toLowerCase(), Double.parseDouble(paramParser.group(2))); + position.set(key, Double.parseDouble(value)); } catch (NumberFormatException e) { - position.set(paramParser.group(1).toLowerCase(), paramParser.group(2)); + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") + || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("y") + || value.equalsIgnoreCase("on")) { + position.set(key, true); + } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("f") + || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("n") + || value.equalsIgnoreCase("off")) { + position.set(key, false); + } else { + position.set(key, value); + } } } } -- cgit v1.2.3 From 345262a970292541c07aee9982c6a26a29c11f9c Mon Sep 17 00:00:00 2001 From: Alexandre Truppel Date: Wed, 22 Feb 2023 15:36:45 +0100 Subject: Boolean special case for Wialon done, added tests --- src/main/java/org/traccar/protocol/WialonProtocolDecoder.java | 10 +++++++--- .../java/org/traccar/protocol/WialonProtocolDecoderTest.java | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 1fc434ed8..4c4ff7a63 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -140,9 +140,13 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { String value = paramParser.group(2); // Key is already in correct type (string) - // If we can parse the value as a double, then we use that as the value's type - // If not, value type is a string unless it is equal to some specific cases (true, yes, etc), in which case we convert into a boolean - + + // If we can parse the value as a double, then we use that as the value's type. + // This covers both integer (x:1:y) and double (x:2:y) types in the Wialon protocol + + // If not, value type is a string unless it is equal to some specific cases + // (true, yes, etc), in which case we convert into a boolean + try { position.set(key, Double.parseDouble(value)); } catch (NumberFormatException e) { diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 6953784fb..45fbfbb1d 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -19,6 +19,12 @@ public class WialonProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;101_521347:1:521246,101_158:1:510,101_521055:1:510,101_521055_2.9:1:509,101_521056:1:3;626B")); + verifyAttributes(decoder, text( + "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:true")); + + verifyAttributes(decoder, text( + "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:false")); + verifyNull(decoder, text( "#L#123456789012345;test")); -- cgit v1.2.3 From ba6a9d72e62282d64781b856b8e094e1fb612f9e Mon Sep 17 00:00:00 2001 From: Alexandre Truppel Date: Wed, 22 Feb 2023 15:50:19 +0100 Subject: Added "setAccuracy" special case, with tests --- .../org/traccar/protocol/WialonProtocolDecoder.java | 11 ++++++++++- .../traccar/protocol/WialonProtocolDecoderTest.java | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 4c4ff7a63..e2ccfe9d8 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -148,7 +148,16 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { // (true, yes, etc), in which case we convert into a boolean try { - position.set(key, Double.parseDouble(value)); + double double_value = Double.parseDouble(value); + + // Since accuracy is not part of the general parameter list, + // we need to handle it separately by calling setAccuracy directly + if (key.equals("accuracy")) { + position.setAccuracy(double_value); + } + else { + position.set(key, double_value); + } } catch (NumberFormatException e) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("y") diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 45fbfbb1d..e25ff7f9e 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -1,8 +1,11 @@ package org.traccar.protocol; +import org.traccar.model.Position; import org.junit.Test; import org.traccar.ProtocolTest; +import static org.junit.Assert.assertEquals; + public class WialonProtocolDecoderTest extends ProtocolTest { @Test @@ -19,12 +22,6 @@ public class WialonProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;101_521347:1:521246,101_158:1:510,101_521055:1:510,101_521055_2.9:1:509,101_521056:1:3;626B")); - verifyAttributes(decoder, text( - "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:true")); - - verifyAttributes(decoder, text( - "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:false")); - verifyNull(decoder, text( "#L#123456789012345;test")); @@ -81,6 +78,15 @@ public class WialonProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, text( "#B#110315;045857;5364.0167;N;06127.8262;E;0;155;965;7;2.40;4;0;14.77,0.02,3.6;AB45DF01145;")); + verifyAttributes(decoder, text( + "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:true")); + + verifyAttributes(decoder, text( + "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:false")); + + Position p = (Position)decoder.decode(null, null, text( + "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;accuracy:2:12.3")); + assertEquals(p.getAccuracy(), 12.3, 0.001); } } -- cgit v1.2.3 From 6c4f99117bbd3645f3b55852b2148beb28c1e0f9 Mon Sep 17 00:00:00 2001 From: Alexandre Truppel Date: Wed, 22 Feb 2023 15:58:43 +0100 Subject: Corrected styling --- src/main/java/org/traccar/protocol/WialonProtocolDecoder.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index e2ccfe9d8..baf3847a1 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -148,15 +148,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { // (true, yes, etc), in which case we convert into a boolean try { - double double_value = Double.parseDouble(value); + double doubleValue = Double.parseDouble(value); // Since accuracy is not part of the general parameter list, // we need to handle it separately by calling setAccuracy directly if (key.equals("accuracy")) { - position.setAccuracy(double_value); - } - else { - position.set(key, double_value); + position.setAccuracy(doubleValue); + } else { + position.set(key, doubleValue); } } catch (NumberFormatException e) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") -- cgit v1.2.3 From 47398e91b1450c744cf3ed31de46f7ea02bbede1 Mon Sep 17 00:00:00 2001 From: Alexandre Truppel Date: Wed, 22 Feb 2023 16:05:21 +0100 Subject: Review --- src/main/java/org/traccar/protocol/WialonProtocolDecoder.java | 10 +++------- .../java/org/traccar/protocol/WialonProtocolDecoderTest.java | 11 ++--------- 2 files changed, 5 insertions(+), 16 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index baf3847a1..1166d0708 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -145,7 +145,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { // This covers both integer (x:1:y) and double (x:2:y) types in the Wialon protocol // If not, value type is a string unless it is equal to some specific cases - // (true, yes, etc), in which case we convert into a boolean + // (true, false), in which case we convert into a boolean try { double doubleValue = Double.parseDouble(value); @@ -158,13 +158,9 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { position.set(key, doubleValue); } } catch (NumberFormatException e) { - if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") - || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("y") - || value.equalsIgnoreCase("on")) { + if (value.equalsIgnoreCase("true")) { position.set(key, true); - } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("f") - || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("n") - || value.equalsIgnoreCase("off")) { + } else if (value.equalsIgnoreCase("false")) { position.set(key, false); } else { position.set(key, value); diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index e25ff7f9e..0a47edcb4 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -78,15 +78,8 @@ public class WialonProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, text( "#B#110315;045857;5364.0167;N;06127.8262;E;0;155;965;7;2.40;4;0;14.77,0.02,3.6;AB45DF01145;")); - verifyAttributes(decoder, text( - "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:true")); - - verifyAttributes(decoder, text( - "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:false")); - - Position p = (Position)decoder.decode(null, null, text( - "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;accuracy:2:12.3")); - assertEquals(p.getAccuracy(), 12.3, 0.001); + verifyAttribute(decoder, text( + "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:false"), "motion", false); } } -- cgit v1.2.3 From a2d9daf4b21313ebaed862f126355becf2b6d4ec Mon Sep 17 00:00:00 2001 From: Alexandre Truppel Date: Wed, 22 Feb 2023 16:07:05 +0100 Subject: Formatting --- .../traccar/protocol/WialonProtocolDecoder.java | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 1166d0708..b319a5947 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -39,31 +39,31 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN_ANY = new PatternBuilder() - .expression("([^#]+)?") // imei - .text("#") // start byte - .expression("([^#]+)") // type - .text("#") // separator - .expression("(.*)") // message + .expression("([^#]+)?") // imei + .text("#") // start byte + .expression("([^#]+)") // type + .text("#") // separator + .expression("(.*)") // message .compile(); private static final Pattern PATTERN = new PatternBuilder() - .number("(?:NA|(dd)(dd)(dd));") // date (ddmmyy) - .number("(?:NA|(dd)(dd)(dd));") // time (hhmmss) - .number("(?:NA|(dd)(dd.d+));") // latitude + .number("(?:NA|(dd)(dd)(dd));") // date (ddmmyy) + .number("(?:NA|(dd)(dd)(dd));") // time (hhmmss) + .number("(?:NA|(dd)(dd.d+));") // latitude .expression("(?:NA|([NS]));") - .number("(?:NA|(ddd)(dd.d+));") // longitude + .number("(?:NA|(ddd)(dd.d+));") // longitude .expression("(?:NA|([EW]));") - .number("(?:NA|(d+.?d*))?;") // speed - .number("(?:NA|(d+.?d*))?;") // course - .number("(?:NA|(-?d+.?d*));") // altitude - .number("(?:NA|(d+))") // satellites + .number("(?:NA|(d+.?d*))?;") // speed + .number("(?:NA|(d+.?d*))?;") // course + .number("(?:NA|(-?d+.?d*));") // altitude + .number("(?:NA|(d+))") // satellites .groupBegin().text(";") - .number("(?:NA|(d+.?d*));") // hdop - .number("(?:NA|(d+));") // inputs - .number("(?:NA|(d+));") // outputs - .expression("(?:NA|([^;]*));") // adc - .expression("(?:NA|([^;]*));") // ibutton - .expression("(?:NA|(.*))") // params + .number("(?:NA|(d+.?d*));") // hdop + .number("(?:NA|(d+));") // inputs + .number("(?:NA|(d+));") // outputs + .expression("(?:NA|([^;]*));") // adc + .expression("(?:NA|([^;]*));") // ibutton + .expression("(?:NA|(.*))") // params .groupEnd("?") .compile(); -- cgit v1.2.3 From 2b7c3ecde2512478dac381feaab9d35a93c3b9cb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Feb 2023 07:15:04 -0800 Subject: Small code cleanup --- .../org/traccar/protocol/WialonProtocolDecoder.java | 18 ++---------------- .../traccar/protocol/WialonProtocolDecoderTest.java | 6 ++---- 2 files changed, 4 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index b319a5947..ffa4472ef 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -135,27 +135,13 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { for (String param : values) { Matcher paramParser = Pattern.compile("(.*):[1-3]:(.*)").matcher(param); if (paramParser.matches()) { - // Parsing gives a (string,string) key-value pair String key = paramParser.group(1).toLowerCase(); String value = paramParser.group(2); - - // Key is already in correct type (string) - - // If we can parse the value as a double, then we use that as the value's type. - // This covers both integer (x:1:y) and double (x:2:y) types in the Wialon protocol - - // If not, value type is a string unless it is equal to some specific cases - // (true, false), in which case we convert into a boolean - try { - double doubleValue = Double.parseDouble(value); - - // Since accuracy is not part of the general parameter list, - // we need to handle it separately by calling setAccuracy directly if (key.equals("accuracy")) { - position.setAccuracy(doubleValue); + position.setAccuracy(Double.parseDouble(value)); } else { - position.set(key, doubleValue); + position.set(key, Double.parseDouble(value)); } } catch (NumberFormatException e) { if (value.equalsIgnoreCase("true")) { diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 0a47edcb4..29a86e0ac 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -1,11 +1,8 @@ package org.traccar.protocol; -import org.traccar.model.Position; import org.junit.Test; import org.traccar.ProtocolTest; -import static org.junit.Assert.assertEquals; - public class WialonProtocolDecoderTest extends ProtocolTest { @Test @@ -79,7 +76,8 @@ public class WialonProtocolDecoderTest extends ProtocolTest { "#B#110315;045857;5364.0167;N;06127.8262;E;0;155;965;7;2.40;4;0;14.77,0.02,3.6;AB45DF01145;")); verifyAttribute(decoder, text( - "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:false"), "motion", false); + "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;motion:3:false"), + "motion", false); } } -- cgit v1.2.3 From 9deca13ced10ef8a6df164831dd60ed4089a25a6 Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Wed, 22 Feb 2023 21:43:47 +0300 Subject: lint patch --- src/main/java/org/traccar/config/Keys.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 53f0336cc..6aa41f85b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1299,25 +1299,29 @@ public final class Keys { public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new BooleanConfigKey( "processing.computedAttributes.deviceAttributes", List.of(KeyType.CONFIG)); + /** * Enable local variables declaration. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES = new BooleanConfigKey( "processing.computedAttributes.localVariables", List.of(KeyType.CONFIG)); + /** * Enable loops processing. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOOPS = new BooleanConfigKey( "processing.computedAttributes.loops", List.of(KeyType.CONFIG)); + /** * Enable new instances creation. - * When disabled, parsing a script/expression using 'new(...)' will throw a parsing exception; using a class as functor will fail. + * When disabled, parsing a script/expression using 'new(...)' will throw a parsing exception; */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION = new BooleanConfigKey( "processing.computedAttributes.newInstanceCreation", List.of(KeyType.CONFIG)); + /** * Boolean flag to enable or disable reverse geocoder. */ -- cgit v1.2.3 From 0fe0344a64b142ef4492ff6ad3c1f8590d336ab0 Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Wed, 22 Feb 2023 22:46:50 +0300 Subject: Alternative features activation way --- src/main/java/org/traccar/config/Keys.java | 8 ++++---- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6aa41f85b..d3bba9ae7 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1299,21 +1299,21 @@ public final class Keys { public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new BooleanConfigKey( "processing.computedAttributes.deviceAttributes", List.of(KeyType.CONFIG)); - + /** * Enable local variables declaration. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES = new BooleanConfigKey( "processing.computedAttributes.localVariables", List.of(KeyType.CONFIG)); - + /** * Enable loops processing. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOOPS = new BooleanConfigKey( "processing.computedAttributes.loops", List.of(KeyType.CONFIG)); - + /** * Enable new instances creation. * When disabled, parsing a script/expression using 'new(...)' will throw a parsing exception; @@ -1321,7 +1321,7 @@ public final class Keys { public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION = new BooleanConfigKey( "processing.computedAttributes.newInstanceCreation", List.of(KeyType.CONFIG)); - + /** * Boolean flag to enable or disable reverse geocoder. */ diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 73b549195..2964d81d7 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -55,6 +55,8 @@ public class ComputedAttributesHandler extends BaseDataHandler { private final JexlEngine engine; + private final JexlFeatures features; + private final boolean includeDeviceAttributes; @Inject @@ -62,7 +64,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { this.cacheManager = cacheManager; JexlSandbox sandbox = new JexlSandbox(false); sandbox.allow("com.safe.Functions"); - JexlFeatures features = new JexlFeatures() + features = new JexlFeatures() .localVar(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES)) .loops(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS)) .newInstance(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION)) @@ -71,7 +73,6 @@ public class ComputedAttributesHandler extends BaseDataHandler { .strict(true) .namespaces(Collections.singletonMap("math", Math.class)) .sandbox(sandbox) - .features(features) .create(); includeDeviceAttributes = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES); } @@ -113,7 +114,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { */ @Deprecated public Object computeAttribute(Attribute attribute, Position position) throws JexlException { - return engine.createExpression(attribute.getExpression()).evaluate(prepareContext(position)); + return engine.createScript(features, engine.createInfo(), attribute.getExpression()).execute(prepareContext(position)); } @Override -- cgit v1.2.3 From 41fe87006c89ee1ddf727878448ba83cb4537ebf Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Wed, 22 Feb 2023 23:11:25 +0300 Subject: Fix Math namespace --- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 2964d81d7..0eab509ee 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -64,6 +64,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { this.cacheManager = cacheManager; JexlSandbox sandbox = new JexlSandbox(false); sandbox.allow("com.safe.Functions"); + sandbox.allow(Math.class.getName()); features = new JexlFeatures() .localVar(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES)) .loops(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS)) -- cgit v1.2.3 From 7a8fc065a116af1f944959354495db00459d2199 Mon Sep 17 00:00:00 2001 From: memesaregood1 Date: Thu, 23 Feb 2023 22:07:42 +0300 Subject: Fix lint issues once again --- src/main/java/org/traccar/config/Keys.java | 8 ++++---- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index d3bba9ae7..6aa41f85b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1299,21 +1299,21 @@ public final class Keys { public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new BooleanConfigKey( "processing.computedAttributes.deviceAttributes", List.of(KeyType.CONFIG)); - + /** * Enable local variables declaration. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES = new BooleanConfigKey( "processing.computedAttributes.localVariables", List.of(KeyType.CONFIG)); - + /** * Enable loops processing. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_LOOPS = new BooleanConfigKey( "processing.computedAttributes.loops", List.of(KeyType.CONFIG)); - + /** * Enable new instances creation. * When disabled, parsing a script/expression using 'new(...)' will throw a parsing exception; @@ -1321,7 +1321,7 @@ public final class Keys { public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_NEW_INSTANCE_CREATION = new BooleanConfigKey( "processing.computedAttributes.newInstanceCreation", List.of(KeyType.CONFIG)); - + /** * Boolean flag to enable or disable reverse geocoder. */ diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 0eab509ee..e8a4998e3 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -115,7 +115,9 @@ public class ComputedAttributesHandler extends BaseDataHandler { */ @Deprecated public Object computeAttribute(Attribute attribute, Position position) throws JexlException { - return engine.createScript(features, engine.createInfo(), attribute.getExpression()).execute(prepareContext(position)); + return engine.createScript(features, + engine.createInfo(), + attribute.getExpression()).execute(prepareContext(position)); } @Override -- cgit v1.2.3 From 1da3bc7bfe9bcd6a7a6fe9105973e93772657597 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Feb 2023 11:19:26 -0800 Subject: Minor formatting change --- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index e8a4998e3..7671fcc2f 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -115,9 +115,8 @@ public class ComputedAttributesHandler extends BaseDataHandler { */ @Deprecated public Object computeAttribute(Attribute attribute, Position position) throws JexlException { - return engine.createScript(features, - engine.createInfo(), - attribute.getExpression()).execute(prepareContext(position)); + return engine.createScript(features,engine.createInfo(), attribute.getExpression()) + .execute(prepareContext(position)); } @Override -- cgit v1.2.3 From b943cdbc7bce5d28e9c32b16b17bf3da6380e031 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Feb 2023 11:22:36 -0800 Subject: Minor formatting change --- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 7671fcc2f..d384bbffc 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -115,7 +115,8 @@ public class ComputedAttributesHandler extends BaseDataHandler { */ @Deprecated public Object computeAttribute(Attribute attribute, Position position) throws JexlException { - return engine.createScript(features,engine.createInfo(), attribute.getExpression()) + return engine + .createScript(features, engine.createInfo(), attribute.getExpression()) .execute(prepareContext(position)); } -- cgit v1.2.3 From 2ac77554f7771a014d62a6e5eeb381b4650dc4f4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Feb 2023 16:20:23 -0800 Subject: Fix short trips and stops --- .../org/traccar/reports/common/ReportUtils.java | 2 +- .../java/org/traccar/reports/ReportUtilsTest.java | 34 +++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index a7c420095..35faa9c8b 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -386,7 +386,7 @@ public class ReportUtils { } } } - if (startEventIndex >= 0 && startEventIndex < positions.size() - 1) { + if (detected & startEventIndex >= 0 && startEventIndex < positions.size() - 1) { int endIndex = startNoEventIndex >= 0 ? startNoEventIndex : positions.size() - 1; result.add(calculateTripOrStop( device, positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 4bf668064..aa166dc25 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -98,8 +98,8 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:03:00.000", 10, 1000), position("2016-01-01 00:04:00.000", 10, 2000), position("2016-01-01 00:05:00.000", 0, 3000), - position("2016-01-01 00:06:00.000", 0, 3000), - position("2016-01-01 00:07:00.000", 0, 3000)); + position("2016-01-01 00:15:00.000", 0, 3000), + position("2016-01-01 00:25:00.000", 0, 3000)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( @@ -136,8 +136,8 @@ public class ReportUtilsTest extends BaseTest { itemStop = iterator.next(); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getStartTime()); - assertEquals(date("2016-01-01 00:07:00.000"), itemStop.getEndTime()); - assertEquals(120000, itemStop.getDuration()); + assertEquals(date("2016-01-01 00:25:00.000"), itemStop.getEndTime()); + assertEquals(1200000, itemStop.getDuration()); } @@ -151,8 +151,8 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:03:00.000", 10, 1000), position("2016-01-01 00:04:00.000", 10, 2000), position("2016-01-01 00:05:00.000", 0, 3000), - position("2016-01-01 00:06:00.000", 0, 3000), - position("2016-01-01 00:07:00.000", 0, 3000)); + position("2016-01-01 00:15:00.000", 0, 3000), + position("2016-01-01 00:25:00.000", 0, 3000)); data.get(5).set(Position.KEY_IGNITION, false); @@ -205,8 +205,8 @@ public class ReportUtilsTest extends BaseTest { itemStop = iterator.next(); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getStartTime()); - assertEquals(date("2016-01-01 00:07:00.000"), itemStop.getEndTime()); - assertEquals(120000, itemStop.getDuration()); + assertEquals(date("2016-01-01 00:25:00.000"), itemStop.getEndTime()); + assertEquals(1200000, itemStop.getDuration()); } @@ -224,8 +224,8 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:07:00.000", 0, 5000), position("2016-01-01 00:08:00.000", 10, 6000), position("2016-01-01 00:09:00.000", 0, 7000), - position("2016-01-01 00:10:00.000", 0, 7000), - position("2016-01-01 00:11:00.000", 0, 7000)); + position("2016-01-01 00:19:00.000", 0, 7000), + position("2016-01-01 00:29:00.000", 0, 7000)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( @@ -262,8 +262,8 @@ public class ReportUtilsTest extends BaseTest { itemStop = iterator.next(); assertEquals(date("2016-01-01 00:09:00.000"), itemStop.getStartTime()); - assertEquals(date("2016-01-01 00:11:00.000"), itemStop.getEndTime()); - assertEquals(120000, itemStop.getDuration()); + assertEquals(date("2016-01-01 00:29:00.000"), itemStop.getEndTime()); + assertEquals(1200000, itemStop.getDuration()); } @@ -332,9 +332,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:00:00.000", 2, 0), position("2016-01-01 00:01:00.000", 1, 0), position("2016-01-01 00:02:00.000", 0, 0), - position("2016-01-01 00:03:00.000", 0, 0), - position("2016-01-01 00:04:00.000", 0, 0), - position("2016-01-01 00:05:00.000", 0, 0)); + position("2016-01-01 00:12:00.000", 0, 0), + position("2016-01-01 00:22:00.000", 0, 0), + position("2016-01-01 00:32:00.000", 0, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( @@ -349,8 +349,8 @@ public class ReportUtilsTest extends BaseTest { StopReportItem itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getStartTime()); - assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); - assertEquals(180000, itemStop.getDuration()); + assertEquals(date("2016-01-01 00:32:00.000"), itemStop.getEndTime()); + assertEquals(1800000, itemStop.getDuration()); } -- cgit v1.2.3 From 9aef1bfcffa0750ba0771dd1af2ffe8667547b3a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Feb 2023 16:30:21 -0800 Subject: Support GPTXT format --- .../org/traccar/protocol/T55ProtocolDecoder.java | 40 +++++++++++++++++++++- .../traccar/protocol/T55ProtocolDecoderTest.java | 3 ++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 3be161fb8..4db76f601 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -150,6 +150,18 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { .number("xx") // checksum .compile(); + private static final Pattern PATTERN_GPTXT = new PatternBuilder() + .text("$GPTXT,") + .text("NET,") + .number("(d+),") // device id + .expression("([^,]+),") // network operator + .number("(-d+),") // rssi + .number("(d+) ") // mcc + .number("(d+)") // mnc + .text("*") + .number("xx") // checksum + .compile(); + private Position position = null; private Position decodeGprmc( @@ -328,6 +340,30 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeGptxt(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_GPTXT, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + + getLastLocation(position, null); + + position.set(Position.KEY_OPERATOR, parser.next()); + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set("mcc", parser.nextInt()); + position.set("mnc", parser.nextInt()); + + return position; + } + private Position decodePubx(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_PUBX, sentence); @@ -421,6 +457,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return decodeQze(channel, remoteAddress, sentence); } else if (sentence.startsWith("$PUBX")) { return decodePubx(channel, remoteAddress, sentence); + } else if (sentence.startsWith("$GPTXT")) { + return decodeGptxt(channel, remoteAddress, sentence); } return null; diff --git a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java index 1622f64f2..e04e473bb 100644 --- a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class T55ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new T55ProtocolDecoder(null)); + verifyAttributes(decoder, text( + "$GPTXT,NET,1003,A1,-53,232 01*77")); + verifyPosition(decoder, text( "$PUBX,00,130209.00,3650.51159,N,01346.10602,E,785.947,D3,4.1,5.2,0.163,87.43,-0.054,7.0,0.88,1.21,0.88,24,01012,0*6D")); -- cgit v1.2.3 From 5b77d6297eaf171595ca0eedb50e434eb073c8ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Feb 2023 15:00:29 -0800 Subject: Configurable TopFly responses --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 6e09e6e3b..758716d23 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -20,6 +20,8 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -511,7 +513,9 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - if (type == MSG_ALARM || type == MSG_ALARM_2) { + boolean acknowledgement = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ACK.withPrefix(getProtocolName()), deviceSession.getDeviceId()); + if (acknowledgement || type == MSG_ALARM || type == MSG_ALARM_2) { sendResponse(channel, header, type, index, imei, alarm); } -- cgit v1.2.3 From dfc546a26f5b7b9486df31ccce812f44bd41168f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Feb 2023 16:12:31 -0800 Subject: Meitrack TA255 battery level --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 5 +++++ src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 5c5ba4be4..3acd87b8f 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -553,6 +553,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // alarm type buf.skipBytes(length - 2); break; + case 0xFEA8: + buf.readUnsignedByte(); // battery status + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + buf.readUnsignedByte(); // battery alert + break; default: buf.skipBytes(length); break; diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 419eddf63..853345521 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "2424663137302c3836353431333035303839313733372c4343452c00000000010088001800050501060907101400150008080000091c000a18000b1e001606001a0000402300fe9000000602d5fe5ffe038f2a1f0904102c8d2b0cd23f02000df03203001c01000000050e0cf90101003170017ac80892ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb20501010000002a36430d0a"), + Position.KEY_BATTERY_LEVEL, 77); + verifyAttribute(decoder, binary( "24245b3131342c3836343630363034343939333938372c4343452c0000000001005000130006012305000600070f1b004702060800000900000a00000b0000199d011a00000602d179570103b25ccc0604cf04862b0cc65b01000da4090d001c01000000010e0ccc010000b627be11000000002a41300d0a"), Position.KEY_LOCK, true); -- cgit v1.2.3 From 0f5c17535ff8a3bd7a8c8a0616535077e5c72d39 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Feb 2023 16:17:43 -0800 Subject: Remove unnecessary conversion --- src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index ddd669b36..b83d24f17 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -130,7 +130,7 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { int index = buf.readUnsignedShortLE(); String id = String.format("%08d%07d", buf.readUnsignedIntLE(), buf.readUnsignedIntLE()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; } -- cgit v1.2.3 From 9a1cbeb7b754b0147d8ccbc334849fac087d7cda Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Feb 2023 22:11:51 -0800 Subject: Meitrack TA255 battery level --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 11 +++++++++-- .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 3acd87b8f..3f1f7f506 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -554,8 +554,15 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(length - 2); break; case 0xFEA8: - buf.readUnsignedByte(); // battery status - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + if (buf.readUnsignedByte() > 0) { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } else { + buf.readUnsignedByte(); + } + buf.readUnsignedByte(); // battery 2 status + buf.readUnsignedByte(); // battery 2 level + buf.readUnsignedByte(); // battery 3 status + buf.readUnsignedByte(); // battery 3 level buf.readUnsignedByte(); // battery alert break; default: diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 853345521..ec45933a3 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -12,7 +12,7 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); verifyAttribute(decoder, binary( - "2424663137302c3836353431333035303839313733372c4343452c00000000010088001800050501060907101400150008080000091c000a18000b1e001606001a0000402300fe9000000602d5fe5ffe038f2a1f0904102c8d2b0cd23f02000df03203001c01000000050e0cf90101003170017ac80892ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb20501010000002a36430d0a"), + "2424593434312c3836353431333035303839313733372c4343452c00000000030088001800050501061607191400150008080000098e000a05000b0c001608001a0000402300fe9000000602c3fe5ffe03e22a1f0904e6688d2b0cd94002000d5f6f03001c01000000050e0cf901010032700298c80899ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb205010000000083001700050501061607191400150008080000098e000a05000b0c001608001a0000405100fe9000000502c3fe5ffe03e22a1f0904e6688d2b0cd94002000d606f0300050e0cf901010032700298c80899ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb205010000000088001800050501061607151400150008080000098e000a05000b0c001607001a0000402300fe9000000602c3fe5ffe03e22a1f0904f0688d2b0cd94002000d696f03001c01000000050e0cf901010032700298c80897ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb20501000000002a36320d0a"), Position.KEY_BATTERY_LEVEL, 77); verifyAttribute(decoder, binary( -- cgit v1.2.3 From 3331593759a21a1fa36cb64332e14828f7e522f0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Feb 2023 19:31:44 -0800 Subject: Fix alarm and driving behavior --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index d0bbeebb5..f79641bcf 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -847,7 +847,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x03: count = buf.readUnsignedByte(); for (int i = 0; i < count; i++) { - int id = buf.readUnsignedShort(); + int id = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); switch (id) { case 0x1A: diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index e91c84d79..04c3a8cd3 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyPosition(decoder, binary( + "7e0900001f4f07788ef87d000cf0230223150215010203013800000c000b029dc58c04b99b60230223171822507e")); + verifyPosition(decoder, binary( "7e0200004107904226220608ca0000010000000010031dac0d004864f30000000000002212291003220104000179a7300107310100eb17000300e151000300e304000b00d801041edf340000306b007e")); -- cgit v1.2.3 From 01ca9d91616d148db30333ae79d3bf3fc13fc1e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 1 Mar 2023 16:21:45 -0800 Subject: Add T24 M2MV2 response --- .../traccar/protocol/TramigoProtocolDecoder.java | 29 +++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index b83d24f17..4a9a9a58f 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -123,23 +124,45 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { } - private Position decode04(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws ParseException { + private Position decode04(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedShortLE(); // length buf.readUnsignedShortLE(); // checksum int index = buf.readUnsignedShortLE(); + long id1 = buf.readUnsignedIntLE(); + long id2 = buf.readUnsignedIntLE(); + long time = buf.readUnsignedIntLE(); - String id = String.format("%08d%07d", buf.readUnsignedIntLE(), buf.readUnsignedIntLE()); + String id = String.format("%08d%07d", id1, id2); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; } + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeByte(0x04); // protocol + response.writeShortLE(24); // length + response.writeShortLE(0); // checksum + response.writeShortLE(index); + response.writeIntLE((int) id1); + response.writeIntLE((int) id2); + response.writeIntLE((int) time); + + response.writeByte(0xff); // acknowledgement + response.writeShortLE(index); + response.writeShortLE(0); // success + + response.setShortLE(3, Checksum.crc16(Checksum.CRC16_CCITT_FALSE, response.nioBuffer())); + + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_INDEX, index); - position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setDeviceTime(new Date(time * 1000)); while (buf.isReadable()) { int type = buf.readUnsignedByte(); -- cgit v1.2.3 From 847e581a4846994474a3116fc17fc16bde658f00 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Mar 2023 14:49:18 -0800 Subject: Decode full IMEI number --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index f79641bcf..3945b86a3 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -169,7 +169,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } else { long imei = id.getUnsignedShort(0); imei = (imei << 32) + id.getUnsignedInt(2); - return String.valueOf(imei); + return String.valueOf(imei) + Checksum.luhn(imei); } } -- cgit v1.2.3 From 6019dd4996fd19fdc9cc52d0e16d66b0397988a0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Mar 2023 16:14:34 -0800 Subject: Support Redis forwarding --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 3 ++ .../traccar/forward/PositionForwarderRedis.java | 50 ++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 src/main/java/org/traccar/forward/PositionForwarderRedis.java (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index 27ab1333b..d452fccca 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "com.amazonaws:aws-java-sdk-sns:1.12.399" implementation "org.apache.kafka:kafka-clients:3.3.2" implementation "com.hivemq:hivemq-mqtt-client:1.3.0" + implementation 'redis.clients:jedis:4.3.1' implementation "com.google.firebase:firebase-admin:9.1.1" testImplementation "junit:junit:4.13.2" testImplementation "org.mockito:mockito-core:4.+" diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index ae637b455..96928b295 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -41,6 +41,7 @@ import org.traccar.forward.EventForwarderMqtt; import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; import org.traccar.forward.PositionForwarderKafka; +import org.traccar.forward.PositionForwarderRedis; import org.traccar.forward.PositionForwarderUrl; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; @@ -348,6 +349,8 @@ public class MainModule extends AbstractModule { return new PositionForwarderJson(config, client, objectMapper); case "kafka": return new PositionForwarderKafka(config, objectMapper); + case "redis": + return new PositionForwarderRedis(config, objectMapper); default: return new PositionForwarderUrl(config, client, objectMapper); } diff --git a/src/main/java/org/traccar/forward/PositionForwarderRedis.java b/src/main/java/org/traccar/forward/PositionForwarderRedis.java new file mode 100644 index 000000000..539d247b6 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderRedis.java @@ -0,0 +1,50 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import redis.clients.jedis.Jedis; + +public class PositionForwarderRedis implements PositionForwarder { + + private final String url; + + private final ObjectMapper objectMapper; + + public PositionForwarderRedis(Config config, ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + this.url = config.getString(Keys.FORWARD_URL); + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + + try { + String key = "positions." + positionData.getDevice().getUniqueId(); + String value = objectMapper.writeValueAsString(positionData.getPosition()); + try (Jedis jedis = new Jedis(url)) { + jedis.lpush(key, value); + } + resultHandler.onResult(true, null); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + +} -- cgit v1.2.3 From d80bf8c6b4e320ec03c0ed31fa460f636f5c6358 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Mar 2023 08:50:31 -0800 Subject: Transparent type response (fix #5040) --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 3945b86a3..d6deafe17 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -294,6 +294,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_TRANSPARENT) { + sendGeneralResponse(channel, remoteAddress, id, type, index); + return decodeTransparent(deviceSession, buf); } -- cgit v1.2.3 From 240fa0061368d27d950443ebf571aa2b6bf9dae3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 6 Mar 2023 09:43:30 -0800 Subject: Explicit switch cases --- src/main/java/org/traccar/MainModule.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 96928b295..ae42d6712 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 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. @@ -333,6 +333,7 @@ public class MainModule extends AbstractModule { return new EventForwarderKafka(config, objectMapper); case "mqtt": return new EventForwarderMqtt(config, objectMapper); + case "json": default: return new EventForwarderJson(config, client); } @@ -351,6 +352,7 @@ public class MainModule extends AbstractModule { return new PositionForwarderKafka(config, objectMapper); case "redis": return new PositionForwarderRedis(config, objectMapper); + case "url": default: return new PositionForwarderUrl(config, client, objectMapper); } -- cgit v1.2.3 From 2749e520c9ea1ba778c120739e2b67a9fe5e119c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Mar 2023 09:26:32 -0800 Subject: Add JT705A gyro axis --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 16 ++++++++++++++++ .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 20 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index d6deafe17..d3336b60c 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -753,6 +753,22 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, status); + while (buf.readableBytes() > 2) { + int id = buf.readUnsignedByte(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x02: + position.setAltitude(buf.readShort()); + break; + case 0x0C: + position.set("gyro", ByteBufUtil.hexDump(buf.readSlice(6))); + break; + default: + buf.skipBytes(length); + break; + } + } + return position; } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 95abc43a7..9590f7732 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( + "7e55019c3b8571110003399a07032310302029538631031015370500001a0c000000265700440001233703080000001001020202000a0a04028f000af401040c06ff98ffa8007e707e"), + "gyro", "ff98ffa8007e"); + verifyPosition(decoder, binary( "7e0900001f4f07788ef87d000cf0230223150215010203013800000c000b029dc58c04b99b60230223171822507e")); -- cgit v1.2.3 From f4d10160d9513eb190169d0ab335c3d99c6d4e31 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Mar 2023 07:34:15 -0800 Subject: Decode bark count --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 4 ++++ .../java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 0b08badb8..aa43a6054 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -277,6 +277,10 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { i += 1; } break; + case 0x37: + buf.readUnsignedIntLE(); // timestamp + position.set("barkCount", BitUtil.to(buf.readUnsignedIntLE(), 31)); + break; case 0x40: buf.readUnsignedIntLE(); // timestamp int heartRate = buf.readUnsignedByte(); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index 2013fa820..693a11fc5 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -10,6 +10,10 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Minifinder2ProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "ab101c00d6f61e000110013836333932313033393939363038300937efd201640c000000"), + "barkCount", 12L); + verifyAttribute(decoder, binary( "ab102600080f1400011001383633393231303339393833343736092429b347633003a96409020000008027b34763"), "bark", true); -- cgit v1.2.3 From 4fc5d0b58b3667ee1bb81515deef6440225af76b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Mar 2023 15:18:18 -0800 Subject: Clean up MQTT forwarder --- src/main/java/org/traccar/forward/EventForwarderMqtt.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java index dc95cb4e2..7f4e29384 100644 --- a/src/main/java/org/traccar/forward/EventForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -21,8 +21,6 @@ import com.hivemq.client.mqtt.datatypes.MqttQos; import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -32,7 +30,6 @@ import java.util.UUID; public class EventForwarderMqtt implements EventForwarder { - private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarderMqtt.class); private final Mqtt5AsyncClient client; private final ObjectMapper objectMapper; @@ -63,7 +60,7 @@ public class EventForwarderMqtt implements EventForwarder { String host = url.getHost(); int port = url.getPort(); client = Mqtt5Client.builder() - .identifier("traccar-" + UUID.randomUUID().toString()) + .identifier("traccar-" + UUID.randomUUID()) .serverHost(host) .serverPort(port) .simpleAuth(simpleAuth) -- cgit v1.2.3 From 08612944b879861c37b34688e0e9ef2d4a8c11a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 12 Mar 2023 11:03:25 -0700 Subject: Implement memory storage --- src/main/java/org/traccar/MainModule.java | 12 +- src/main/java/org/traccar/config/Keys.java | 7 ++ .../java/org/traccar/storage/MemoryStorage.java | 126 ++++++++++++++++++++- 3 files changed, 141 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index ae42d6712..663747de1 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -84,6 +84,7 @@ import org.traccar.sms.SnsSmsClient; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.DatabaseStorage; +import org.traccar.storage.MemoryStorage; import org.traccar.storage.Storage; import org.traccar.web.WebServer; @@ -108,10 +109,19 @@ public class MainModule extends AbstractModule { protected void configure() { bindConstant().annotatedWith(Names.named("configFile")).to(configFile); bind(Config.class).asEagerSingleton(); - bind(Storage.class).to(DatabaseStorage.class).in(Scopes.SINGLETON); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } + @Singleton + @Provides + public static Storage provideStorage(Injector injector, Config config) { + if (config.getBoolean(Keys.DATABASE_MEMORY)) { + return injector.getInstance(MemoryStorage.class); + } else { + return injector.getInstance(DatabaseStorage.class); + } + } + @Singleton @Provides public static ObjectMapper provideObjectMapper(Config config) { diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6aa41f85b..1b4b3a5b4 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -385,6 +385,13 @@ public final class Keys { List.of(KeyType.CONFIG), 25.0); + /** + * Enable in-memory database instead of an SQL database. + */ + public static final ConfigKey DATABASE_MEMORY = new BooleanConfigKey( + "database.memory", + List.of(KeyType.CONFIG)); + /** * Path to the database driver JAR file. Traccar includes drivers for MySQL, PostgreSQL and H2 databases. If you use * one of those, you don't need to specify this parameter. diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index f19897ff8..9b5db1209 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -18,35 +18,155 @@ package org.traccar.storage; import org.traccar.model.BaseModel; import org.traccar.model.Pair; import org.traccar.model.Permission; +import org.traccar.model.Server; +import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import java.beans.Introspector; +import java.lang.reflect.Method; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; public class MemoryStorage extends Storage { + private final Map, Map> objects = new HashMap<>(); private final Map, Class>, Set>> permissions = new HashMap<>(); + private final AtomicLong increment = new AtomicLong(); + + public MemoryStorage() { + Server server = new Server(); + server.setId(1); + server.setRegistration(true); + objects.put(Server.class, Map.of(server.getId(), server)); + } + @Override public List getObjects(Class clazz, Request request) { - return null; + return objects.computeIfAbsent(clazz, key -> new HashMap<>()).values().stream() + .filter(object -> checkCondition(request.getCondition(), object)) + .map(object -> (T) object) + .collect(Collectors.toList()); + } + + private boolean checkCondition(Condition genericCondition, Object object) { + if (genericCondition == null) { + return true; + } + + if (genericCondition instanceof Condition.Compare) { + + var condition = (Condition.Compare) genericCondition; + Object value = retrieveValue(object, condition.getVariable()); + int result = ((Comparable) value).compareTo(condition.getValue()); + switch (condition.getOperator()) { + case "<": + return result < 0; + case "<=": + return result <= 0; + case ">": + return result > 0; + case ">=": + return result >= 0; + case "=": + return result == 0; + default: + throw new RuntimeException("Unsupported comparison condition"); + } + + } else if (genericCondition instanceof Condition.Between) { + + var condition = (Condition.Between) genericCondition; + Object fromValue = retrieveValue(object, condition.getFromVariable()); + int fromResult = ((Comparable) fromValue).compareTo(condition.getFromValue()); + Object toValue = retrieveValue(object, condition.getToVariable()); + int toResult = ((Comparable) toValue).compareTo(condition.getToValue()); + return fromResult >= 0 && toResult <= 0; + + } else if (genericCondition instanceof Condition.Binary) { + + var condition = (Condition.Binary) genericCondition; + if (condition.getOperator().equals("AND")) { + return checkCondition(condition.getFirst(), object) && checkCondition(condition.getSecond(), object); + } else if (condition.getOperator().equals("OR")) { + return checkCondition(condition.getFirst(), object) || checkCondition(condition.getSecond(), object); + } + + } else if (genericCondition instanceof Condition.Permission) { + + var condition = (Condition.Permission) genericCondition; + long id = (Long) retrieveValue(object, "id"); + return getPermissionsSet(condition.getOwnerClass(), condition.getPropertyClass()).stream() + .anyMatch(pair -> { + if (condition.getOwnerId() > 0) { + return pair.getFirst() == condition.getOwnerId() && pair.getSecond() == id; + } else { + return pair.getFirst() == id && pair.getSecond() == condition.getPropertyId(); + } + }); + + } else if (genericCondition instanceof Condition.LatestPositions) { + + return false; + + } + + return false; + } + + private Object retrieveValue(Object object, String key) { + try { + Method method = object.getClass().getMethod( + "get" + Character.toUpperCase(key.charAt(0)) + key.substring(1)); + return method.invoke(object); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } } @Override public long addObject(T entity, Request request) { - return 0; + long id = increment.incrementAndGet(); + objects.computeIfAbsent(entity.getClass(), key -> new HashMap<>()).put(id, entity); + return id; } @Override public void updateObject(T entity, Request request) { + Set columns = new HashSet<>(request.getColumns().getColumns(entity.getClass(), "get")); + Collection items; + if (request.getCondition() != null) { + long id = (Long) ((Condition.Equals) request.getCondition()).getValue(); + items = List.of(objects.computeIfAbsent(entity.getClass(), key -> new HashMap<>()).get(id)); + } else { + items = objects.computeIfAbsent(entity.getClass(), key -> new HashMap<>()).values(); + } + for (Method setter : entity.getClass().getMethods()) { + if (setter.getName().startsWith("set") && setter.getParameterCount() == 1 + && columns.contains(Introspector.decapitalize(setter.getName()))) { + try { + Method getter = entity.getClass().getMethod(setter.getName().replaceFirst("set", "get")); + Object value = getter.invoke(entity); + for (Object object : items) { + setter.invoke(object, value); + } + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + } } @Override public void removeObject(Class clazz, Request request) { + long id = (Long) ((Condition.Equals) request.getCondition()).getValue(); + objects.computeIfAbsent(clazz, key -> new HashMap<>()).remove(id); } private Set> getPermissionsSet(Class ownerClass, Class propertyClass) { -- cgit v1.2.3 From 016c107821a6df94a6f71659f9f067334fbc75fd Mon Sep 17 00:00:00 2001 From: bernamaxim Date: Mon, 13 Mar 2023 11:53:43 +0700 Subject: RegisterUnknown filter with regex #5023 update PR #5044 --- setup/default.xml | 2 ++ src/main/java/org/traccar/config/Keys.java | 7 +++++++ src/main/java/org/traccar/session/ConnectionManager.java | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/setup/default.xml b/setup/default.xml index 75acf25a1..f7f1af15b 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -39,6 +39,8 @@ true true + \w{3,15} + ./schema/changelog-master.xml 5001 diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 1b4b3a5b4..7896f0dc4 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -494,6 +494,13 @@ public final class Keys { "database.registerUnknown.defaultGroupId", List.of(KeyType.CONFIG)); + /** + * Automatically register unknown devices with regex filter. + */ + public static final ConfigKey DATABASE_REGISTER_UNKNOWN_REGEX = new StringConfigKey( + "database.registerUnknown.regex", + List.of(KeyType.CONFIG)); + /** * Store empty messages as positions. For example, heartbeats. */ diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 37a42d827..e6f5d00cf 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -123,7 +123,9 @@ public class ConnectionManager implements BroadcastInterface { Device device = deviceLookupService.lookup(uniqueIds); if (device == null && config.getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { - device = addUnknownDevice(uniqueIds[0]); + if (uniqueIds[0].matches(config.getString(Keys.DATABASE_REGISTER_UNKNOWN_REGEX))) { + device = addUnknownDevice(uniqueIds[0]); + } } if (device != null) { -- cgit v1.2.3 From 0ed96dc475883bf2d56e6308089d6891ca521b18 Mon Sep 17 00:00:00 2001 From: Bernard Date: Mon, 13 Mar 2023 22:36:21 +0700 Subject: Update Keys.java --- src/main/java/org/traccar/config/Keys.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 7896f0dc4..3c7346833 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -499,7 +499,7 @@ public final class Keys { */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN_REGEX = new StringConfigKey( "database.registerUnknown.regex", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), "\w{3,15}"); /** * Store empty messages as positions. For example, heartbeats. -- cgit v1.2.3 From fc0b4234d1d0d668769819b40c476a51beab0c1d Mon Sep 17 00:00:00 2001 From: Bernard Date: Mon, 13 Mar 2023 23:26:53 +0700 Subject: Update Keys.java --- src/main/java/org/traccar/config/Keys.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 3c7346833..491c724aa 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -499,7 +499,7 @@ public final class Keys { */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN_REGEX = new StringConfigKey( "database.registerUnknown.regex", - List.of(KeyType.CONFIG), "\w{3,15}"); + List.of(KeyType.CONFIG), "\\w{3,15}"); /** * Store empty messages as positions. For example, heartbeats. -- cgit v1.2.3 From 5c0962c257d51bef081d25405c972dd54035a0b2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Mar 2023 09:43:34 -0700 Subject: Add bark stopped flag --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index aa43a6054..37e86e243 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -279,7 +279,11 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { break; case 0x37: buf.readUnsignedIntLE(); // timestamp - position.set("barkCount", BitUtil.to(buf.readUnsignedIntLE(), 31)); + long barking = buf.readUnsignedIntLE(); + if (BitUtil.check(barking, 31)) { + position.set("barkStop", true); + } + position.set("barkCount", BitUtil.to(barking, 31)); break; case 0x40: buf.readUnsignedIntLE(); // timestamp -- cgit v1.2.3 From d4816aae87600334fe798e8b50b9f11df6f0b293 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Mar 2023 09:55:19 -0700 Subject: Option for system only emails --- src/main/java/org/traccar/api/resource/PasswordResource.java | 2 +- src/main/java/org/traccar/config/Keys.java | 7 +++++++ src/main/java/org/traccar/mail/LogMailManager.java | 10 ++++++---- src/main/java/org/traccar/mail/MailManager.java | 8 +++++--- src/main/java/org/traccar/mail/SmtpMailManager.java | 10 ++++++---- src/main/java/org/traccar/notificators/NotificatorMail.java | 2 +- src/main/java/org/traccar/reports/common/ReportMailer.java | 2 +- 7 files changed, 27 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 2d87a8665..67c9cee97 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -63,7 +63,7 @@ public class PasswordResource extends BaseResource { if (user != null) { var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); + mailManager.sendMessage(user, true, fullMessage.getSubject(), fullMessage.getBody()); } return Response.ok().build(); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 491c724aa..cb1ee63e1 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -835,6 +835,13 @@ public final class Keys { "mail.debug", List.of(KeyType.CONFIG)); + /** + * Restrict global SMTP configuration to system messages only (e.g. password reset). + */ + public static final ConfigKey MAIL_SMTP_SYSTEM_ONLY = new BooleanConfigKey( + "mail.smtp.systemOnly", + List.of(KeyType.CONFIG)); + /** * Force SMTP settings from the config file and ignore user attributes. */ diff --git a/src/main/java/org/traccar/mail/LogMailManager.java b/src/main/java/org/traccar/mail/LogMailManager.java index 4af68809c..5c7572b0c 100644 --- a/src/main/java/org/traccar/mail/LogMailManager.java +++ b/src/main/java/org/traccar/mail/LogMailManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -32,12 +32,14 @@ public class LogMailManager implements MailManager { } @Override - public void sendMessage(User user, String subject, String body) throws MessagingException { - sendMessage(user, subject, body, null); + public void sendMessage( + User user, boolean system, String subject, String body) throws MessagingException { + sendMessage(user, system, subject, body, null); } @Override - public void sendMessage(User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + public void sendMessage( + User user, boolean system, String subject, String body, MimeBodyPart attachment) throws MessagingException { LOGGER.info( "Email sent\nTo: {}\nSubject: {}\nAttachment: {}\nBody:\n{}", user.getEmail(), subject, attachment != null ? attachment.getFileName() : null, body); diff --git a/src/main/java/org/traccar/mail/MailManager.java b/src/main/java/org/traccar/mail/MailManager.java index 69efbed32..3547fd37e 100644 --- a/src/main/java/org/traccar/mail/MailManager.java +++ b/src/main/java/org/traccar/mail/MailManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -24,8 +24,10 @@ public interface MailManager { boolean getEmailEnabled(); - void sendMessage(User user, String subject, String body) throws MessagingException; + void sendMessage( + User user, boolean system, String subject, String body) throws MessagingException; - void sendMessage(User user, String subject, String body, MimeBodyPart attachment) throws MessagingException; + void sendMessage( + User user, boolean system, String subject, String body, MimeBodyPart attachment) throws MessagingException; } diff --git a/src/main/java/org/traccar/mail/SmtpMailManager.java b/src/main/java/org/traccar/mail/SmtpMailManager.java index 4a0b7048f..8d1afbd3e 100644 --- a/src/main/java/org/traccar/mail/SmtpMailManager.java +++ b/src/main/java/org/traccar/mail/SmtpMailManager.java @@ -93,19 +93,21 @@ public final class SmtpMailManager implements MailManager { return config.hasKey(Keys.MAIL_SMTP_HOST); } + @Override public void sendMessage( - User user, String subject, String body) throws MessagingException { - sendMessage(user, subject, body, null); + User user, boolean system, String subject, String body) throws MessagingException { + sendMessage(user, system, subject, body, null); } + @Override public void sendMessage( - User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + User user, boolean system, String subject, String body, MimeBodyPart attachment) throws MessagingException { Properties properties = null; if (!config.getBoolean(Keys.MAIL_SMTP_IGNORE_USER_CONFIG)) { properties = getProperties(new PropertiesProvider(user)); } - if (properties == null) { + if (properties == null && (system || !config.getBoolean(Keys.MAIL_SMTP_SYSTEM_ONLY))) { properties = getProperties(new PropertiesProvider(config)); } if (properties == null) { diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 7f755f170..8818a5a75 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -44,7 +44,7 @@ public class NotificatorMail implements Notificator { 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()); + mailManager.sendMessage(user, false, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); } diff --git a/src/main/java/org/traccar/reports/common/ReportMailer.java b/src/main/java/org/traccar/reports/common/ReportMailer.java index 221b35ae1..3ce41934f 100644 --- a/src/main/java/org/traccar/reports/common/ReportMailer.java +++ b/src/main/java/org/traccar/reports/common/ReportMailer.java @@ -55,7 +55,7 @@ public class ReportMailer { stream.toByteArray(), "application/octet-stream"))); User user = permissionsService.getUser(userId); - mailManager.sendMessage(user, "Report", "The report is in the attachment.", attachment); + mailManager.sendMessage(user, false, "Report", "The report is in the attachment.", attachment); } catch (StorageException | IOException | MessagingException e) { LOGGER.warn("Email report failed", e); } -- cgit v1.2.3 From 765f1bdbe7418a8808faf578e2dcf1adc6094bc9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Mar 2023 17:57:25 -0700 Subject: Fix device id --- src/main/java/org/traccar/protocol/T55ProtocolDecoder.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 4db76f601..b18359b3f 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -353,6 +353,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); -- cgit v1.2.3 From ffe4c83b226308932e8a1c1388104c9070a3184b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Mar 2023 21:53:15 -0700 Subject: Support HuaSheng commands --- .../org/traccar/protocol/HuaShengProtocol.java | 9 ++- .../traccar/protocol/HuaShengProtocolDecoder.java | 4 +- .../traccar/protocol/HuaShengProtocolEncoder.java | 71 ++++++++++++++++++++++ .../protocol/HuaShengProtocolEncoderTest.java | 23 +++++++ 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java create mode 100644 src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index b1b61e977..4a0ebe5d7 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 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 org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import org.traccar.model.Command; import javax.inject.Inject; @@ -26,10 +27,16 @@ public class HuaShengProtocol extends BaseProtocol { @Inject public HuaShengProtocol(Config config) { + setSupportedDataCommands( + Command.TYPE_POSITION_PERIODIC, + Command.TYPE_ALARM_ARM, + Command.TYPE_ALARM_DISARM, + Command.TYPE_SET_SPEED_LIMIT); addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuaShengFrameDecoder()); + pipeline.addLast(new HuaShengProtocolEncoder(HuaShengProtocol.this)); pipeline.addLast(new HuaShengProtocolDecoder(HuaShengProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 371691d82..993e36978 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 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. @@ -48,6 +48,8 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_UPFAULT_RSP = 0xFF13; public static final int MSG_HSO_REQ = 0x0002; public static final int MSG_HSO_RSP = 0x0003; + public static final int MSG_SET_REQ = 0xAA04; + public static final int MSG_SET_RSP = 0xFF05; private void sendResponse(Channel channel, int type, int index, ByteBuf content) { if (channel != null) { diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java new file mode 100644 index 000000000..636196ec4 --- /dev/null +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java @@ -0,0 +1,71 @@ +/* + * 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.buffer.Unpooled; +import org.traccar.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.model.Command; + +public class HuaShengProtocolEncoder extends BaseProtocolEncoder { + + public HuaShengProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private ByteBuf encodeContent(ByteBuf content) { + + ByteBuf buf = Unpooled.buffer(); + buf.writeByte(0xC0); + buf.writeShort(0x0000); // flag and version + buf.writeShort(12 + content.readableBytes()); + buf.writeShort(HuaShengProtocolDecoder.MSG_SET_REQ); + buf.writeShort(0); // checksum + buf.writeInt(1); // index + buf.writeBytes(content); + content.release(); + buf.writeByte(0xC0); + + return buf; + } + + @Override + protected Object encodeCommand(Command command) { + + ByteBuf content = Unpooled.buffer(0); + switch (command.getType()) { + case Command.TYPE_POSITION_PERIODIC: + content.writeShort(0x0002); + content.writeShort(6); // length + content.writeShort(command.getInteger(Command.KEY_FREQUENCY)); + return encodeContent(content); + case Command.TYPE_ALARM_ARM: + case Command.TYPE_ALARM_DISARM: + content.writeShort(0x0001); + content.writeShort(5); // length + content.writeByte(command.getType().equals(Command.TYPE_ALARM_ARM) ? 1 : 0); + case Command.TYPE_SET_SPEED_LIMIT: + content.writeShort(0x0004); + content.writeShort(6); // length + content.writeShort(command.getInteger(Command.KEY_DATA)); + return encodeContent(content); + default: + return null; + } + } + +} diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java new file mode 100644 index 000000000..b44f6e89c --- /dev/null +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.jupiter.api.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class HuaShengProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + var encoder = inject(new HuaShengProtocolEncoder(null)); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_POSITION_PERIODIC); + command.set(Command.KEY_FREQUENCY, 60); + + verifyCommand(encoder, command, binary("c000000012aa0400000000000100020006003cc0")); + + } + +} -- cgit v1.2.3 From 2d20fbd1740f302af5a1e7522e728c0939a323a0 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Tue, 21 Mar 2023 15:16:49 +0000 Subject: changed-session-retreival-permission-to-manager --- src/main/java/org/traccar/api/resource/SessionResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 7025d5fa7..ff84c135f 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -123,7 +123,7 @@ public class SessionResource extends BaseResource { @Path("{id}") @GET public User get(@PathParam("id") long userId) throws StorageException { - permissionsService.checkAdmin(getUserId()); + permissionsService.checkUser(getUserId(), userId); User user = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", userId))); request.getSession().setAttribute(USER_ID_KEY, user.getId()); -- cgit v1.2.3 From 2a0b2dee5eecd55f86c51fe2a25f7ac7484d6bde Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 21 Mar 2023 13:40:50 -0700 Subject: Response after position processed --- src/main/java/org/traccar/BasePipelineFactory.java | 16 ++- .../java/org/traccar/ExtendedObjectDecoder.java | 12 +- src/main/java/org/traccar/MainEventHandler.java | 3 + src/main/java/org/traccar/config/Keys.java | 7 ++ .../traccar/handler/AcknowledgementHandler.java | 121 +++++++++++++++++++++ .../java/org/traccar/handler/FilterHandler.java | 23 ++-- .../org/traccar/handler/FilterHandlerTest.java | 18 +-- 7 files changed, 177 insertions(+), 23 deletions(-) create mode 100644 src/main/java/org/traccar/handler/AcknowledgementHandler.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index b184da45c..70f999c72 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -25,6 +25,7 @@ import io.netty.channel.ChannelPipeline; import io.netty.handler.timeout.IdleStateHandler; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.handler.AcknowledgementHandler; import org.traccar.handler.ComputedAttributesHandler; import org.traccar.handler.CopyAttributesHandler; import org.traccar.handler.DefaultDataHandler; @@ -60,15 +61,19 @@ public abstract class BasePipelineFactory extends ChannelInitializer { private final Injector injector; private final TrackerConnector connector; private final String protocol; - private int timeout; + private final boolean instantAcknowledgement; + private final int timeout; public BasePipelineFactory(TrackerConnector connector, Config config, String protocol) { this.injector = Main.getInjector(); this.connector = connector; this.protocol = protocol; - timeout = config.getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); + instantAcknowledgement = config.getBoolean(Keys.SERVER_INSTANT_ACKNOWLEDGEMENT); + int timeout = config.getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); if (timeout == 0) { - timeout = config.getInteger(Keys.SERVER_TIMEOUT); + this.timeout = config.getInteger(Keys.SERVER_TIMEOUT); + } else { + this.timeout = timeout; } } @@ -112,6 +117,9 @@ public abstract class BasePipelineFactory extends ChannelInitializer { pipeline.addLast(new OpenChannelHandler(connector)); pipeline.addLast(new NetworkMessageHandler()); pipeline.addLast(new StandardLoggingHandler(protocol)); + if (!instantAcknowledgement) { + pipeline.addLast(new AcknowledgementHandler()); + } addProtocolHandlers(handler -> { if (handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder) { diff --git a/src/main/java/org/traccar/ExtendedObjectDecoder.java b/src/main/java/org/traccar/ExtendedObjectDecoder.java index f79a36c85..805f98cb7 100644 --- a/src/main/java/org/traccar/ExtendedObjectDecoder.java +++ b/src/main/java/org/traccar/ExtendedObjectDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -23,6 +23,7 @@ import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.handler.AcknowledgementHandler; import org.traccar.helper.DataConverter; import org.traccar.model.Position; @@ -30,6 +31,7 @@ import javax.inject.Inject; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; +import java.util.List; public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter { @@ -68,6 +70,7 @@ public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { NetworkMessage networkMessage = (NetworkMessage) msg; Object originalMessage = networkMessage.getMessage(); + ctx.writeAndFlush(new AcknowledgementHandler.EventReceived()); try { Object decodedMessage = decode(ctx.channel(), networkMessage.getRemoteAddress(), originalMessage); onMessageEvent(ctx.channel(), networkMessage.getRemoteAddress(), originalMessage, decodedMessage); @@ -76,14 +79,19 @@ public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter } if (decodedMessage != null) { if (decodedMessage instanceof Collection) { - for (Object o : (Collection) decodedMessage) { + var collection = (Collection) decodedMessage; + ctx.writeAndFlush(new AcknowledgementHandler.EventDecoded(collection)); + for (Object o : collection) { saveOriginal(o, originalMessage); ctx.fireChannelRead(o); } } else { + ctx.writeAndFlush(new AcknowledgementHandler.EventDecoded(List.of(decodedMessage))); saveOriginal(decodedMessage, originalMessage); ctx.fireChannelRead(decodedMessage); } + } else { + ctx.writeAndFlush(new AcknowledgementHandler.EventDecoded(List.of())); } } finally { ReferenceCountUtil.release(originalMessage); diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 877f03ae7..658ff6d6d 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; +import org.traccar.handler.AcknowledgementHandler; import org.traccar.helper.DateUtil; import org.traccar.helper.NetworkUtil; import org.traccar.helper.model.PositionUtil; @@ -145,6 +146,8 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.info(builder.toString()); statisticsManager.registerMessageStored(position.getDeviceId(), position.getProtocol()); + + ctx.writeAndFlush(new AcknowledgementHandler.EventHandled(position)); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index cb1ee63e1..c207efb1e 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -292,6 +292,13 @@ public final class Keys { "server.timeout", List.of(KeyType.CONFIG)); + /** + * Send device responses immediately before writing it in the database. + */ + public static final ConfigKey SERVER_INSTANT_ACKNOWLEDGEMENT = new BooleanConfigKey( + "server.instantAcknowledgement", + List.of(KeyType.CONFIG)); + /** * Address for uploading aggregated anonymous usage statistics. Uploaded information is the same you can see on the * statistics screen in the web app. It does not include any sensitive (e.g. locations). diff --git a/src/main/java/org/traccar/handler/AcknowledgementHandler.java b/src/main/java/org/traccar/handler/AcknowledgementHandler.java new file mode 100644 index 000000000..c3f6038de --- /dev/null +++ b/src/main/java/org/traccar/handler/AcknowledgementHandler.java @@ -0,0 +1,121 @@ +/* + * 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.handler; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundHandlerAdapter; +import io.netty.channel.ChannelPromise; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class AcknowledgementHandler extends ChannelOutboundHandlerAdapter { + + private static final Logger LOGGER = LoggerFactory.getLogger(AcknowledgementHandler.class); + + public interface Event { + } + + public static class EventReceived implements Event { + } + + public static class EventDecoded implements Event { + private final Collection objects; + + public EventDecoded(Collection objects) { + this.objects = objects; + } + + public Collection getObjects() { + return objects; + } + } + + public static class EventHandled implements Event { + private final Object object; + + public EventHandled(Object object) { + this.object = object; + } + + public Object getObject() { + return object; + } + } + + private static class Entry { + private final Object message; + private final ChannelPromise promise; + + private Entry(Object message, ChannelPromise promise) { + this.message = message; + this.promise = promise; + } + + public Object getMessage() { + return message; + } + + public ChannelPromise getPromise() { + return promise; + } + } + + private List queue; + private final Set waiting = new HashSet<>(); + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + List output = new LinkedList<>(); + synchronized (this) { + if (msg instanceof Event) { + if (msg instanceof EventReceived) { + LOGGER.debug("Event received"); + if (queue == null) { + queue = new LinkedList<>(); + } + } else if (msg instanceof EventDecoded) { + EventDecoded event = (EventDecoded) msg; + LOGGER.debug("Event decoded {}", event.getObjects().size()); + waiting.addAll(event.getObjects()); + } else if (msg instanceof EventHandled) { + EventHandled event = (EventHandled) msg; + LOGGER.debug("Event handled"); + waiting.remove(event.getObject()); + } + if (!(msg instanceof EventReceived) && waiting.isEmpty()) { + output.addAll(queue); + queue = null; + } + } else if (queue != null) { + LOGGER.debug("Message queued"); + queue.add(new Entry(msg, promise)); + } else { + LOGGER.debug("Message sent"); + output.add(new Entry(msg, promise)); + } + } + for (Entry entry : output) { + ctx.write(entry.getMessage(), entry.getPromise()); + } + } + +} diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 994276bb6..1d1c27b7a 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 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 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. @@ -16,9 +16,10 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; @@ -39,7 +40,7 @@ import java.util.Date; @Singleton @ChannelHandler.Sharable -public class FilterHandler extends BaseDataHandler { +public class FilterHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(FilterHandler.class); @@ -177,7 +178,7 @@ public class FilterHandler extends BaseDataHandler { return false; } - private boolean filter(Position position) { + protected boolean filter(Position position) { StringBuilder filterType = new StringBuilder(); @@ -243,11 +244,17 @@ public class FilterHandler extends BaseDataHandler { } @Override - protected Position handlePosition(Position position) { - if (enabled && filter(position)) { - return null; + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (msg instanceof Position) { + Position position = (Position) msg; + if (enabled && filter(position)) { + ctx.writeAndFlush(new AcknowledgementHandler.EventHandled(position)); + } else { + ctx.fireChannelRead(position); + } + } else { + super.channelRead(ctx, msg); } - return position; } } diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java index 9cb4a3bf2..26281e351 100644 --- a/src/test/java/org/traccar/handler/FilterHandlerTest.java +++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java @@ -11,8 +11,8 @@ import org.traccar.session.cache.CacheManager; import java.util.Date; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; @@ -71,18 +71,18 @@ public class FilterHandlerTest extends BaseTest { Position position = createPosition(new Date(), true, 10); - assertNotNull(filteringHandler.handlePosition(position)); - assertNotNull(passingHandler.handlePosition(position)); + assertFalse(filteringHandler.filter(position)); + assertFalse(passingHandler.filter(position)); position = createPosition(new Date(Long.MAX_VALUE), true, 10); - assertNull(filteringHandler.handlePosition(position)); - assertNotNull(passingHandler.handlePosition(position)); + assertTrue(filteringHandler.filter(position)); + assertFalse(passingHandler.filter(position)); position = createPosition(new Date(), false, 10); - assertNull(filteringHandler.handlePosition(position)); - assertNotNull(passingHandler.handlePosition(position)); + assertTrue(filteringHandler.filter(position)); + assertFalse(passingHandler.filter(position)); } @@ -92,7 +92,7 @@ public class FilterHandlerTest extends BaseTest { Position position = createPosition(new Date(), true, 0); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - assertNotNull(filteringHandler.handlePosition(position)); + assertFalse(filteringHandler.filter(position)); } -- cgit v1.2.3 From a07e078645418720ad4bbe4ce352cae607c42175 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 21 Mar 2023 13:44:14 -0700 Subject: Fix lint check --- src/main/java/org/traccar/handler/AcknowledgementHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/AcknowledgementHandler.java b/src/main/java/org/traccar/handler/AcknowledgementHandler.java index c3f6038de..4c1085998 100644 --- a/src/main/java/org/traccar/handler/AcknowledgementHandler.java +++ b/src/main/java/org/traccar/handler/AcknowledgementHandler.java @@ -61,7 +61,7 @@ public class AcknowledgementHandler extends ChannelOutboundHandlerAdapter { } } - private static class Entry { + private static final class Entry { private final Object message; private final ChannelPromise promise; -- cgit v1.2.3 From 5f56a56d77216fa46a63eabbcef67d59d4d7c817 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 21 Mar 2023 21:46:12 -0700 Subject: Support BS50 battery info --- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 64 +++++++++++++++++++++- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 4 ++ 2 files changed, 67 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index b343c3b33..2b50e55c2 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -15,8 +15,11 @@ */ 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.helper.DataConverter; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -448,6 +451,63 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeBms(Channel channel, SocketAddress remoteAddress, String sentence) { + String id = sentence.substring(1, 13); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + ByteBuf buf = Unpooled.wrappedBuffer( + DataConverter.parseHex(sentence.substring(1 + 12 + 4, sentence.length() - 1))); + + buf.readUnsignedByte(); + buf.readUnsignedByte(); + buf.readUnsignedByte(); // header + + int batteryCount = buf.readUnsignedByte(); + for (int i = 1; i <= 24; i++) { + int voltage = buf.readUnsignedShortLE(); + if (i <= batteryCount) { + position.set("battery" + i, voltage * 0.001); + } + } + + position.set(Position.KEY_CHARGE, buf.readUnsignedByte() == 0); + position.set("current", buf.readUnsignedShortLE() * 0.1); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set("batteryOverheat", buf.readUnsignedByte() > 0); + position.set("chargeProtection", buf.readUnsignedByte() > 0); + position.set("dischargeProtection", buf.readUnsignedByte() > 0); + buf.readUnsignedByte(); // drop line + buf.readUnsignedByte(); // balanced + position.set("cycles", buf.readUnsignedShortLE()); + position.set("faultAlarm", buf.readUnsignedByte()); + + buf.skipBytes(6); + + int temperatureCount = buf.readUnsignedByte(); + position.set("powerTemp", buf.readUnsignedByte() - 40); + position.set("equilibriumTemp", buf.readUnsignedByte() - 40); + for (int i = 1; i <= 7; i++) { + int temperature = buf.readUnsignedByte() - 40; + if (i <= temperatureCount) { + position.set("batteryTemp" + i, temperature); + } + } + + position.set("calibrationCapacity", buf.readUnsignedShortLE() * 0.01); + position.set("dischargeCapacity", buf.readUnsignedIntLE()); + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -477,6 +537,8 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return decodeLbsWifi(channel, remoteAddress, sentence); } else if (sentence.contains("BV00")) { return decodeVin(channel, remoteAddress, sentence); + } else if (sentence.contains("BS50")) { + return decodeBms(channel, remoteAddress, sentence); } Parser parser = new Parser(PATTERN, sentence); diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 9fc8b81b2..1631ab051 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Tk103ProtocolDecoder(null)); + verifyAttribute(decoder, text( + "(352602014867BS500064FF0EF10FF10FF00FF20FF30FF20FF20FF40FF20FF40FF40FF20FF30FF20F0000000000000000000000000000000000000000000000001663000000010004000000000000000002444444420000000000A00FA000000000000000200000000315E2000000)"), + "batteryTemp2", 26); + verifyAttributes(decoder, text( "(027046434858BZ00,{460,0,20949,58711}\n{460,0,20494,54003}\n{460,0,20951,19569}\n,01000000)")); -- cgit v1.2.3 From 2bb447924b834693f4d97585f1e5e9e822b62fe3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Mar 2023 07:57:06 -0700 Subject: Encoder bypass other events --- src/main/java/org/traccar/BaseProtocolEncoder.java | 45 +++++++++++----------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 9c3934184..96de3e3f0 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -71,31 +71,30 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - NetworkMessage networkMessage = (NetworkMessage) msg; - - if (networkMessage.getMessage() instanceof Command) { - - Command command = (Command) networkMessage.getMessage(); - Object encodedCommand = encodeCommand(ctx.channel(), command); - - StringBuilder s = new StringBuilder(); - s.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); - s.append("id: ").append(getUniqueId(command.getDeviceId())).append(", "); - s.append("command type: ").append(command.getType()).append(" "); - if (encodedCommand != null) { - s.append("sent"); - } else { - s.append("not sent"); + if (msg instanceof NetworkMessage) { + NetworkMessage networkMessage = (NetworkMessage) msg; + if (networkMessage.getMessage() instanceof Command) { + + Command command = (Command) networkMessage.getMessage(); + Object encodedCommand = encodeCommand(ctx.channel(), command); + + StringBuilder s = new StringBuilder(); + s.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); + s.append("id: ").append(getUniqueId(command.getDeviceId())).append(", "); + s.append("command type: ").append(command.getType()).append(" "); + if (encodedCommand != null) { + s.append("sent"); + } else { + s.append("not sent"); + } + LOGGER.info(s.toString()); + + ctx.write(new NetworkMessage(encodedCommand, networkMessage.getRemoteAddress()), promise); + + return; } - LOGGER.info(s.toString()); - - ctx.write(new NetworkMessage(encodedCommand, networkMessage.getRemoteAddress()), promise); - - } else { - - super.write(ctx, msg, promise); - } + super.write(ctx, msg, promise); } protected Object encodeCommand(Channel channel, Command command) { -- cgit v1.2.3 From f8fb3f67bc0bc44f9da89c3dabbec7406751e3c6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Mar 2023 09:07:24 -0700 Subject: Decode TZone magnetic card --- .../org/traccar/protocol/TzoneProtocolDecoder.java | 37 ++++++++++++++-------- .../traccar/protocol/TzoneProtocolDecoderTest.java | 4 +++ 2 files changed, 27 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 8e84a6781..ba9b41654 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -204,30 +204,39 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } - private void decodeTags(Position position, ByteBuf buf) { + private void decodeTags(Position position, ByteBuf buf, int hardware) { int blockLength = buf.readUnsignedShort(); int blockEnd = buf.readerIndex() + blockLength; if (blockLength > 0) { - buf.readUnsignedByte(); // tag type + int type = buf.readUnsignedByte(); - int count = buf.readUnsignedByte(); - int tagLength = buf.readUnsignedByte(); + if (hardware != 0x153 || type >= 2) { - for (int i = 1; i <= count; i++) { - int tagEnd = buf.readerIndex() + tagLength; + int count = buf.readUnsignedByte(); + int tagLength = buf.readUnsignedByte(); + + for (int i = 1; i <= count; i++) { + int tagEnd = buf.readerIndex() + tagLength; + + buf.readUnsignedByte(); // status + buf.readUnsignedShortLE(); // battery voltage - buf.readUnsignedByte(); // status - buf.readUnsignedShortLE(); // battery voltage + position.set(Position.PREFIX_TEMP + i, (buf.readShortLE() & 0x3fff) * 0.1); + + buf.readUnsignedByte(); // humidity + buf.readUnsignedByte(); // rssi + + buf.readerIndex(tagEnd); + } - position.set(Position.PREFIX_TEMP + i, (buf.readShortLE() & 0x3fff) * 0.1); + } else if (type == 1) { - buf.readUnsignedByte(); // humidity - buf.readUnsignedByte(); // rssi + position.set("driverLicense", buf.readCharSequence( + blockEnd - buf.readerIndex(), StandardCharsets.UTF_8).toString()); - buf.readerIndex(tagEnd); } } @@ -364,9 +373,9 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } - if (hardware == 0x406) { + if (hardware == 0x153 || hardware == 0x406) { - decodeTags(position, buf); + decodeTags(position, buf, hardware); } diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java index 4813021fd..8fdc8c23c 100644 --- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -10,6 +10,10 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TzoneProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "545a00d424240153011300000863835029944118170316023b180016040485c73d2479187e170316023b1800000000060c000000000d1cc0406303019904aa00000000008a012520205e544f4e474c4f4d245049544f4f4e244d522e5e5e3f3b363030373634333132303130303134323234323d3139303631393538313032363d3f2b2020202020202020202020202032322020202020202020202020203120202020202020202020202030303234363238202031303730302020202020202020202020202020202020202020203f00030080000006e80e0d0a"), + "driverLicense", "% ^TONGLOM$PITOON$MR.^^?;6007643120100142242=190619581026=?+ 22 1 0024628 10700 ?"); + verifyAttributes(decoder, binary( "545a003724240407020200000180322000001610160b151019100000000c010a07320101088600007dca000baa102837016a0114025500000169e80d0a")); -- cgit v1.2.3 From ee3cbd4aba2e7df2ac2da4292caa87a63b171a87 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Mar 2023 19:21:07 -0700 Subject: Decode JT705A tilt --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 14 +++++++++++++- .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index d3336b60c..22c39c2da 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -761,7 +761,19 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(buf.readShort()); break; case 0x0C: - position.set("gyro", ByteBufUtil.hexDump(buf.readSlice(6))); + int x = buf.readUnsignedShort(); + if (x > 0x8000) { + x -= 0x10000; + } + int y = buf.readUnsignedShort(); + if (y > 0x8000) { + y -= 0x10000; + } + int z = buf.readUnsignedShort(); + if (z > 0x8000) { + z -= 0x10000; + } + position.set("tilt", String.format("[%d,%d,%d]", x, y, z)); break; default: buf.skipBytes(length); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 9590f7732..1737593e4 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -16,7 +16,7 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyAttribute(decoder, binary( "7e55019c3b8571110003399a07032310302029538631031015370500001a0c000000265700440001233703080000001001020202000a0a04028f000af401040c06ff98ffa8007e707e"), - "gyro", "ff98ffa8007e"); + "tilt", "[-104,-88,126]"); verifyPosition(decoder, binary( "7e0900001f4f07788ef87d000cf0230223150215010203013800000c000b029dc58c04b99b60230223171822507e")); -- cgit v1.2.3 From f73263da4800f86203e1aa425b0b7d3243d4b7c3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Mar 2023 09:17:25 -0700 Subject: Add JT808 power and battery --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 22c39c2da..ddc3192eb 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -329,6 +329,13 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x03: position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); break; + case 0x56: + buf.readUnsignedByte(); // power level + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; + case 0x61: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + break; case 0x80: position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); break; -- cgit v1.2.3 From 7c2f9e56ba5f699d22ec2939408357b5a220bacc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Mar 2023 09:38:30 -0700 Subject: Fix Wialon parameter decoding --- src/main/java/org/traccar/protocol/WialonProtocolDecoder.java | 3 ++- src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index ffa4472ef..4d1b34dba 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -63,8 +63,9 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { .number("(?:NA|(d+));") // outputs .expression("(?:NA|([^;]*));") // adc .expression("(?:NA|([^;]*));") // ibutton - .expression("(?:NA|(.*))") // params + .expression("(?:NA|([^;]*))") // params .groupEnd("?") + .any() .compile(); private void sendResponse(Channel channel, SocketAddress remoteAddress, String type, Integer number) { diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index e67a798ff..b7c422456 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -13,6 +13,10 @@ public class WialonProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "#L#2.0;42001300083;;CE45")); + verifyAttribute(decoder, text( + "#D#220323;114150;2234.80479;N;11354.87786;E;0;NA;59;11;NA;NA;NA;;NA;d_battr:1:94,d_csq:1:21,di_light:1:1;E7C9"), + "di_light", 1.0); + verifyAttributes(decoder, text( "#D#NA;NA;5429.681944502211763;N;02654.60403650999069;E;NA;NA;NA;NA;NA;NA;NA;1.0;NA;m1:1:9196679,d1:1:15397,t1:1:20,b1:1:162,fuel1:2:21588.0,pv1:2:35.98,finish:1:1;0x9b0")); -- cgit v1.2.3 From b083371beb7b5d32b8ce91da60e10dd3cf8b4c6b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Mar 2023 09:51:52 -0700 Subject: Decode alarm code and input --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 2 ++ src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 758716d23..4ddea730c 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -400,6 +400,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { int alarm = buf.readUnsignedByte(); position.set(Position.KEY_ALARM, header != 0x2727 ? decodeAlarm1(alarm) : decodeAlarm2(alarm)); + position.set("alarmCode", alarm); if (header != 0x2727) { @@ -470,6 +471,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { int inputStatus = buf.readUnsignedShort(); position.set(Position.KEY_IGNITION, BitUtil.check(inputStatus, 2)); position.set(Position.KEY_RSSI, BitUtil.between(inputStatus, 4, 11)); + position.set(Position.KEY_INPUT, inputStatus); buf.readUnsignedShort(); // ignition on upload interval buf.readUnsignedInt(); // ignition off upload interval diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java index 246687149..3f62a834c 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class T800xProtocolDecoderTest extends ProtocolTest { var decoder = inject(new T800xProtocolDecoder(null)); + verifyAttributes(decoder, binary( + "272704004901380864112055585747c612230321220006000036435fc8acc2ee600f420000000000000000909019003900001356a18000012c0000a8c00000001e20d4800000c00000")); + verifyAttributes(decoder, binary( "2525110055000208677300508924902206262035310c540045004c00430045004c0004454447450847534d20313930300f323134303734323036373835323839143839333430373131373930303936383037363846")); -- cgit v1.2.3 From d4efbfa2a7d9d8410540fd2b6409c4086da9cec5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Mar 2023 16:23:12 -0700 Subject: Add JT808 driver information --- .../traccar/protocol/HuabaoProtocolDecoder.java | 23 +++++++++++++++------- .../protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index ddc3192eb..7227c5584 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -457,6 +457,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { int subtype = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); int endIndex = buf.readerIndex() + length; + String stringValue; switch (subtype) { case 0x01: position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); @@ -474,9 +475,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; case 0x33: - String sentence = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); - if (sentence.startsWith("*M00")) { - String lockStatus = sentence.substring(8, 8 + 7); + stringValue = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + if (stringValue.startsWith("*M00")) { + String lockStatus = stringValue.substring(8, 8 + 7); position.set(Position.KEY_BATTERY, Integer.parseInt(lockStatus.substring(2, 5)) * 0.01); } break; @@ -501,8 +502,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { break; case 0x94: if (length > 0) { - position.set( - Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); + stringValue = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + position.set(Position.KEY_VIN, stringValue); } break; case 0xA7: @@ -512,6 +513,14 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0xAC: position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); break; + case 0xBC: + stringValue = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + position.set("driver", stringValue.trim()); + break; + case 0xBD: + stringValue = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + position.set(Position.KEY_DRIVER_UNIQUE_ID, stringValue); + break; case 0xD0: long userStatus = buf.readUnsignedInt(); if (BitUtil.check(userStatus, 3)) { @@ -598,8 +607,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } break; case 0xED: - String license = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString().trim(); - position.set("driverLicense", license); + stringValue = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + position.set("driverLicense", stringValue.trim()); break; case 0xEE: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 1737593e4..4541185f4 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( + "7E02000079013653183645009E00000000000C0C030158BF0006C926670000004000CE22120904274201040000005DBC3244524956494E47204C4943454E53452454455354244D522E0000000000000000000000000000000000000000000000000000BD0F323431393939393935383030313030E3060000050500007102000C30011F310108987E"), + "driver", "DRIVING LICENSE$TEST$MR."); + verifyAttribute(decoder, binary( "7e55019c3b8571110003399a07032310302029538631031015370500001a0c000000265700440001233703080000001001020202000a0a04028f000af401040c06ff98ffa8007e707e"), "tilt", "[-104,-88,126]"); -- cgit v1.2.3 From e6960c3d49025eb63243052e4c7aedde9955fe40 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Mar 2023 07:37:46 -0700 Subject: Support Wetrust GPS tracker --- src/main/java/org/traccar/model/Position.java | 2 ++ .../java/org/traccar/protocol/FifotrackProtocolDecoder.java | 8 ++++---- .../java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 12 +++++++++++- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- .../java/org/traccar/protocol/MeiligaoProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- .../java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ .../java/org/traccar/protocol/TzoneProtocolDecoderTest.java | 3 ++- 10 files changed, 28 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 41cfeaf2e..2bd71f383 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -90,6 +90,7 @@ public class Position extends Message { public static final String KEY_ICCID = "iccid"; public static final String KEY_PHONE = "phone"; public static final String KEY_SPEED_LIMIT = "speedLimit"; + public static final String KEY_DRIVING_TIME = "drivingTime"; public static final String KEY_DTCS = "dtcs"; public static final String KEY_OBD_SPEED = "obdSpeed"; // knots @@ -98,6 +99,7 @@ public class Position extends Message { public static final String KEY_RESULT = "result"; public static final String KEY_DRIVER_UNIQUE_ID = "driverUniqueId"; + public static final String KEY_CARD = "card"; // Start with 1 not 0 public static final String PREFIX_TEMP = "temp"; diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index a9d77b46e..e0dd1d62d 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -308,11 +308,11 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext()) { - String rfid = parser.next(); - if (rfid.matches("\\p{XDigit}+")) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(Integer.parseInt(rfid, 16))); + String value = parser.next(); + if (value.matches("\\p{XDigit}+")) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(Integer.parseInt(value, 16))); } else { - position.set("driverLicense", rfid); + position.set(Position.KEY_CARD, value); } } diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 28308ab77..c7713bdc2 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -680,7 +680,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Double.parseDouble(values[index - 1]))); } if (BitUtil.check(reportMask, 12)) { - position.set("drivingHours", Double.parseDouble(values[index++])); + position.set(Position.KEY_DRIVING_TIME, Double.parseDouble(values[index++])); } if (BitUtil.check(reportMask, 13)) { position.set("idleHours", Double.parseDouble(values[index++])); diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 5b639ddfc..02a629103 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -119,6 +119,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { SPACE10X, STANDARD, OBD6, + WETRUST, } private Variant variant; @@ -833,7 +834,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); buf.readUnsignedByte(); // alarm buf.readUnsignedByte(); // swiped - position.set("driverLicense", data.trim()); + position.set(Position.KEY_CARD, data.trim()); } else if (variant == Variant.BENWAY) { int mask = buf.readUnsignedShort(); position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); @@ -869,6 +870,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } position.set(Position.PREFIX_TEMP + 1, temperature); position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); + } else if (variant == Variant.WETRUST) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_CARD, buf.readCharSequence( + buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString()); + position.set(Position.KEY_ALARM, buf.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); + position.set("cardStatus", buf.readUnsignedByte()); + position.set(Position.KEY_DRIVING_TIME, buf.readUnsignedShort()); } } @@ -1391,6 +1399,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.SPACE10X; } else if (header == 0x7878 && type == MSG_STATUS && length == 0x13) { variant = Variant.OBD6; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x29) { + variant = Variant.WETRUST; } else { variant = Variant.STANDARD; } diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 7227c5584..5e73967d5 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -608,7 +608,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { break; case 0xED: stringValue = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); - position.set("driverLicense", stringValue.trim()); + position.set(Position.KEY_CARD, stringValue.trim()); break; case 0xEE: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index f3b56973a..1f8c4d2da 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -282,7 +282,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, parser.nextHexInt()); position.set(Position.KEY_ODOMETER, parser.nextHexLong()); position.set(Position.KEY_SATELLITES, parser.nextHexInt()); - position.set("driverLicense", parser.next()); + position.set(Position.KEY_CARD, parser.next()); position.set(Position.KEY_ODOMETER, parser.nextLong()); position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index ba9b41654..f0b1e709d 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -234,7 +234,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } else if (type == 1) { - position.set("driverLicense", buf.readCharSequence( + position.set(Position.KEY_CARD, buf.readCharSequence( blockEnd - buf.readerIndex(), StandardCharsets.UTF_8).toString()); } diff --git a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java index a8fc801e7..1ad15f39c 100644 --- a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -123,7 +123,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { position.set("tripStart", decodeDate(buf).getTime()); position.set("tripEnd", decodeDate(buf).getTime()); - position.set("drivingTime", buf.readUnsignedShort()); + position.set(Position.KEY_DRIVING_TIME, buf.readUnsignedShort()); position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 3b4cb158e..5dc6b803e 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78782912170316053b3bcf015b51220af1201105d56100000000000000000000869c0130010000000238d1af0d0a"), + Position.KEY_DRIVING_TIME, 0); + verifyAttribute(decoder, binary( "78781219012ed042cc00954d00040419000056fe290d0a"), Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java index 8fdc8c23c..d90e5e07e 100644 --- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class TzoneProtocolDecoderTest extends ProtocolTest { @@ -12,7 +13,7 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { verifyAttribute(decoder, binary( "545a00d424240153011300000863835029944118170316023b180016040485c73d2479187e170316023b1800000000060c000000000d1cc0406303019904aa00000000008a012520205e544f4e474c4f4d245049544f4f4e244d522e5e5e3f3b363030373634333132303130303134323234323d3139303631393538313032363d3f2b2020202020202020202020202032322020202020202020202020203120202020202020202020202030303234363238202031303730302020202020202020202020202020202020202020203f00030080000006e80e0d0a"), - "driverLicense", "% ^TONGLOM$PITOON$MR.^^?;6007643120100142242=190619581026=?+ 22 1 0024628 10700 ?"); + Position.KEY_CARD, "% ^TONGLOM$PITOON$MR.^^?;6007643120100142242=190619581026=?+ 22 1 0024628 10700 ?"); verifyAttributes(decoder, binary( "545a003724240407020200000180322000001610160b151019100000000c010a07320101088600007dca000baa102837016a0114025500000169e80d0a")); -- cgit v1.2.3 From 3082f7b3e5bfd00ec6f6801222060dfc0d10b7e0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 26 Mar 2023 06:54:29 -0700 Subject: Implement group commands --- .../org/traccar/api/resource/CommandResource.java | 20 ++++++--- .../java/org/traccar/helper/model/DeviceUtil.java | 48 +++++++++++++++++++++- .../traccar/reports/CombinedReportProvider.java | 3 +- .../org/traccar/reports/EventsReportProvider.java | 5 ++- .../org/traccar/reports/RouteReportProvider.java | 5 ++- .../org/traccar/reports/StopsReportProvider.java | 5 ++- .../org/traccar/reports/SummaryReportProvider.java | 3 +- .../org/traccar/reports/TripsReportProvider.java | 5 ++- .../org/traccar/reports/common/ReportUtils.java | 40 ------------------ 9 files changed, 78 insertions(+), 56 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 3460cf6e0..7ba1ee2b4 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -23,8 +23,10 @@ import org.traccar.BaseProtocol; import org.traccar.ServerManager; import org.traccar.api.ExtendedObjectResource; import org.traccar.database.CommandsManager; +import org.traccar.helper.model.DeviceUtil; import org.traccar.model.Command; import org.traccar.model.Device; +import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; @@ -104,7 +106,7 @@ public class CommandResource extends ExtendedObjectResource { @POST @Path("send") - public Response send(Command entity) throws Exception { + public Response send(Command entity, @QueryParam("groupId") long groupId) throws Exception { if (entity.getId() > 0) { permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); long deviceId = entity.getDeviceId(); @@ -114,11 +116,19 @@ public class CommandResource extends ExtendedObjectResource { } else { permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); } - permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); - if (!commandsManager.sendCommand(entity)) { - return Response.accepted(entity).build(); + boolean result = true; + if (groupId > 0) { + permissionsService.checkPermission(Group.class, getUserId(), groupId); + var devices = DeviceUtil.getAccessibleDevices(storage, getUserId(), List.of(), List.of(groupId)); + for (Device device : devices) { + entity.setDeviceId(device.getId()); + result = result && commandsManager.sendCommand(entity); + } + } else { + permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); + result = commandsManager.sendCommand(entity); } - return Response.ok(entity).build(); + return result ? Response.ok(entity).build() : Response.accepted(entity).build(); } @GET diff --git a/src/main/java/org/traccar/helper/model/DeviceUtil.java b/src/main/java/org/traccar/helper/model/DeviceUtil.java index 597078caf..5d8cb5f25 100644 --- a/src/main/java/org/traccar/helper/model/DeviceUtil.java +++ b/src/main/java/org/traccar/helper/model/DeviceUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -16,11 +16,20 @@ package org.traccar.helper.model; import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.Objects; +import java.util.stream.Collectors; + public final class DeviceUtil { private DeviceUtil() { @@ -30,4 +39,41 @@ public final class DeviceUtil { storage.updateObject(new Device(), new Request(new Columns.Include("status"))); } + + public static Collection getAccessibleDevices( + Storage storage, long userId, + Collection deviceIds, Collection groupIds) throws StorageException { + + var devices = storage.getObjects(Device.class, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, Device.class))); + var deviceById = devices.stream() + .collect(Collectors.toUnmodifiableMap(Device::getId, x -> x)); + var devicesByGroup = devices.stream() + .filter(x -> x.getGroupId() > 0) + .collect(Collectors.groupingBy(Device::getGroupId)); + + var groups = storage.getObjects(Group.class, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, Group.class))); + var groupsByGroup = groups.stream() + .filter(x -> x.getGroupId() > 0) + .collect(Collectors.groupingBy(Group::getGroupId)); + + var results = deviceIds.stream() + .map(deviceById::get) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + var groupQueue = new LinkedList<>(groupIds); + while (!groupQueue.isEmpty()) { + long groupId = groupQueue.pop(); + results.addAll(devicesByGroup.getOrDefault(groupId, Collections.emptyList())); + groupQueue.addAll(groupsByGroup.getOrDefault(groupId, Collections.emptyList()) + .stream().map(Group::getId).collect(Collectors.toUnmodifiableList())); + } + + return results; + } + } diff --git a/src/main/java/org/traccar/reports/CombinedReportProvider.java b/src/main/java/org/traccar/reports/CombinedReportProvider.java index 923fd12b4..63d6a9830 100644 --- a/src/main/java/org/traccar/reports/CombinedReportProvider.java +++ b/src/main/java/org/traccar/reports/CombinedReportProvider.java @@ -15,6 +15,7 @@ */ package org.traccar.reports; +import org.traccar.helper.model.DeviceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; @@ -53,7 +54,7 @@ public class CombinedReportProvider { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { CombinedReportItem item = new CombinedReportItem(); item.setDeviceId(device.getId()); var positions = PositionUtil.getPositions(storage, device.getId(), from, to); diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 30f55ba80..ff7bc8e2f 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -19,6 +19,7 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.model.DeviceUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -76,7 +77,7 @@ public class EventsReportProvider { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Event event : events) { @@ -104,7 +105,7 @@ public class EventsReportProvider { HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); HashMap positions = new HashMap<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 3ee651619..6d44259e6 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -19,6 +19,7 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.model.DeviceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -60,7 +61,7 @@ public class RouteReportProvider { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { result.addAll(PositionUtil.getPositions(storage, device.getId(), from, to)); } return result; @@ -73,7 +74,7 @@ public class RouteReportProvider { ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { var positions = PositionUtil.getPositions(storage, device.getId(), from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); deviceRoutes.setDeviceName(device.getName()); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index ec3fd2215..a23cee48b 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -19,6 +19,7 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.model.DeviceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -67,7 +68,7 @@ public class StopsReportProvider { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { result.addAll(detectStops(device, from, to)); } return result; @@ -80,7 +81,7 @@ public class StopsReportProvider { ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { Collection stops = detectStops(device, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); deviceStops.setDeviceName(device.getName()); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 9415f3e81..f7d9f0325 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -21,6 +21,7 @@ import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.DeviceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.Device; @@ -146,7 +147,7 @@ public class SummaryReportProvider { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { Collection deviceResults = calculateSummaryResults(userId, device, from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 265811354..2d8989b7a 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -19,6 +19,7 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.model.DeviceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -67,7 +68,7 @@ public class TripsReportProvider { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { result.addAll(detectTrips(device, from, to)); } return result; @@ -80,7 +81,7 @@ public class TripsReportProvider { ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { Collection trips = detectTrips(device, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); deviceTrips.setDeviceName(device.getName()); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 35faa9c8b..f1a2f7d54 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -36,7 +36,6 @@ import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; -import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; @@ -60,13 +59,9 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Date; -import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Objects; -import java.util.stream.Collectors; @Singleton public class ReportUtils { @@ -106,41 +101,6 @@ public class ReportUtils { } } - public Collection getAccessibleDevices( - long userId, Collection deviceIds, Collection groupIds) throws StorageException { - - var devices = storage.getObjects(Device.class, new Request( - new Columns.All(), - new Condition.Permission(User.class, userId, Device.class))); - var deviceById = devices.stream() - .collect(Collectors.toUnmodifiableMap(Device::getId, x -> x)); - var devicesByGroup = devices.stream() - .filter(x -> x.getGroupId() > 0) - .collect(Collectors.groupingBy(Device::getGroupId)); - - var groups = storage.getObjects(Group.class, new Request( - new Columns.All(), - new Condition.Permission(User.class, userId, Group.class))); - var groupsByGroup = groups.stream() - .filter(x -> x.getGroupId() > 0) - .collect(Collectors.groupingBy(Group::getGroupId)); - - var results = deviceIds.stream() - .map(deviceById::get) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - var groupQueue = new LinkedList<>(groupIds); - while (!groupQueue.isEmpty()) { - long groupId = groupQueue.pop(); - results.addAll(devicesByGroup.getOrDefault(groupId, Collections.emptyList())); - groupQueue.addAll(groupsByGroup.getOrDefault(groupId, Collections.emptyList()) - .stream().map(Group::getId).collect(Collectors.toUnmodifiableList())); - } - - return results; - } - public double calculateFuel(Position firstPosition, Position lastPosition) { if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null -- 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 'src/main/java/org') 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 a5a2a3f69fd76602f5577354cde653915e8d8ad4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Mar 2023 07:33:28 -0700 Subject: Fix VLT type decoding --- src/main/java/org/traccar/protocol/VltProtocolDecoder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/VltProtocolDecoder.java b/src/main/java/org/traccar/protocol/VltProtocolDecoder.java index 8890dece1..01c0563f5 100644 --- a/src/main/java/org/traccar/protocol/VltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VltProtocolDecoder.java @@ -124,13 +124,15 @@ public class VltProtocolDecoder extends BaseHttpProtocolDecoder { switch (type) { case "NRM": return decodePosition(deviceSession, sentence.substring(3 + 15)); - default: + case "BTH": 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; + default: + return null; } } -- cgit v1.2.3 From 7aa7d2d98e2fd7fb36c50711bf6e547c829d6d58 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Mar 2023 09:19:53 -0700 Subject: Flespi battery level support --- src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 6e6f9c700..a7f6c284a 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -125,12 +125,10 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_PDOP, ((JsonNumber) value).doubleValue()); return true; case "din": + position.set(Position.KEY_INPUT, ((JsonNumber) value).intValue()); + return true; case "dout": - if (name.equals("din")) { - position.set(Position.KEY_INPUT, ((JsonNumber) value).intValue()); - } else { - position.set(Position.KEY_OUTPUT, ((JsonNumber) value).intValue()); - } + position.set(Position.KEY_OUTPUT, ((JsonNumber) value).intValue()); return true; case "gps.vehicle.mileage": position.set(Position.KEY_ODOMETER, ((JsonNumber) value).doubleValue()); @@ -141,6 +139,9 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { case "battery.voltage": position.set(Position.KEY_BATTERY, ((JsonNumber) value).doubleValue()); return true; + case "battery.level": + position.set(Position.KEY_BATTERY_LEVEL, ((JsonNumber) value).intValue()); + return true; case "fuel.level": case "can.fuel.level": position.set(Position.KEY_FUEL_LEVEL, ((JsonNumber) value).doubleValue()); -- cgit v1.2.3 From 56c6fd3cfa7140d899ff8e964754e856a8c8b0d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Mar 2023 09:52:16 -0700 Subject: Check disabled users --- src/main/java/org/traccar/api/security/SecurityRequestFilter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index 9992d49e7..e6641548a 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.resource.SessionResource; @@ -63,6 +64,9 @@ public class SecurityRequestFilter implements ContainerRequestFilter { @Inject private StatisticsManager statisticsManager; + @Inject + private Injector injector; + @Override public void filter(ContainerRequestContext requestContext) { @@ -97,13 +101,14 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { + injector.getInstance(PermissionsService.class).getUser(userId).checkDisabled(); statisticsManager.registerRequest(userId); securityContext = new UserSecurityContext(new UserPrincipal(userId)); } } - } catch (SecurityException e) { + } catch (SecurityException | StorageException e) { LOGGER.warn("Authentication error", e); } -- cgit v1.2.3 From 1d1fc57b3dd44013bd467a825b970ac06749e125 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Mar 2023 17:53:19 -0700 Subject: Handle Firebase failures --- .../traccar/notificators/NotificatorFirebase.java | 52 +++++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 9fa2ebaf3..d80354d7d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -25,7 +25,10 @@ import com.google.firebase.messaging.ApnsConfig; import com.google.firebase.messaging.Aps; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.MessagingErrorCode; import com.google.firebase.messaging.MulticastMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; @@ -34,24 +37,40 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; +import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedList; import java.util.List; @Singleton public class NotificatorFirebase implements Notificator { + private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorFirebase.class); + private final NotificationFormatter notificationFormatter; + private final Storage storage; + private final CacheManager cacheManager; @Inject - public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter) throws IOException { + public NotificatorFirebase( + Config config, NotificationFormatter notificationFormatter, + Storage storage, CacheManager cacheManager) throws IOException { this.notificationFormatter = notificationFormatter; + this.storage = storage; + this.cacheManager = cacheManager; InputStream serviceAccount = new ByteArrayInputStream( config.getString(Keys.NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT).getBytes()); @@ -69,7 +88,8 @@ public class NotificatorFirebase implements Notificator { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); - List registrationTokens = Arrays.asList(user.getString("notificationTokens").split("[, ]")); + List registrationTokens = new ArrayList<>( + Arrays.asList(user.getString("notificationTokens").split("[, ]"))); MulticastMessage message = MulticastMessage.builder() .setNotification(com.google.firebase.messaging.Notification.builder() @@ -92,13 +112,33 @@ public class NotificatorFirebase implements Notificator { try { var result = FirebaseMessaging.getInstance().sendMulticast(message); - for (var response : result.getResponses()) { + List failedTokens = new LinkedList<>(); + var iterator = result.getResponses().listIterator(); + while (iterator.hasNext()) { + int index = iterator.nextIndex(); + var response = iterator.next(); if (!response.isSuccessful()) { - throw new MessageException(response.getException()); + MessagingErrorCode error = response.getException().getMessagingErrorCode(); + if (error == MessagingErrorCode.INVALID_ARGUMENT || error == MessagingErrorCode.UNREGISTERED) { + failedTokens.add(registrationTokens.get(index)); + } + LOGGER.warn("Firebase user {} error", user.getId(), response.getException()); + } + } + if (!failedTokens.isEmpty()) { + registrationTokens.removeAll(failedTokens); + if (registrationTokens.isEmpty()) { + user.getAttributes().remove("notificationTokens"); + } else { + user.set("notificationTokens", String.join(",", registrationTokens)); } + storage.updateObject(user, new Request( + new Columns.Include("attributes"), + new Condition.Equals("id", user.getId()))); + cacheManager.updateOrInvalidate(true, user); } - } catch (FirebaseMessagingException e) { - throw new MessageException(e); + } catch (FirebaseMessagingException | StorageException e) { + LOGGER.warn("Firebase error", e); } } } -- cgit v1.2.3 From c68e92043cb52f859de724781f2e5774c60d465b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Mar 2023 20:05:05 -0700 Subject: Add HuaSheng output control --- .../org/traccar/protocol/HuaShengProtocol.java | 1 + .../traccar/protocol/HuaShengProtocolDecoder.java | 2 ++ .../traccar/protocol/HuaShengProtocolEncoder.java | 22 ++++++++++++++++++---- .../protocol/HuaShengProtocolEncoderTest.java | 12 +++++++++++- 4 files changed, 32 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index 4a0ebe5d7..1f8bafc57 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -29,6 +29,7 @@ public class HuaShengProtocol extends BaseProtocol { public HuaShengProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_PERIODIC, + Command.TYPE_OUTPUT_CONTROL, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_SET_SPEED_LIMIT); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 993e36978..2d952c759 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -50,6 +50,8 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_HSO_RSP = 0x0003; public static final int MSG_SET_REQ = 0xAA04; public static final int MSG_SET_RSP = 0xFF05; + public static final int MSG_CTRL_REQ = 0xAA16; + public static final int MSG_CTRL_RSP = 0xFF17; private void sendResponse(Channel channel, int type, int index, ByteBuf content) { if (channel != null) { diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java index 636196ec4..dc34f7b4e 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java @@ -27,13 +27,13 @@ public class HuaShengProtocolEncoder extends BaseProtocolEncoder { super(protocol); } - private ByteBuf encodeContent(ByteBuf content) { + private ByteBuf encodeContent(int type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(); buf.writeByte(0xC0); buf.writeShort(0x0000); // flag and version buf.writeShort(12 + content.readableBytes()); - buf.writeShort(HuaShengProtocolDecoder.MSG_SET_REQ); + buf.writeShort(type); buf.writeShort(0); // checksum buf.writeInt(1); // index buf.writeBytes(content); @@ -52,17 +52,31 @@ public class HuaShengProtocolEncoder extends BaseProtocolEncoder { content.writeShort(0x0002); content.writeShort(6); // length content.writeShort(command.getInteger(Command.KEY_FREQUENCY)); - return encodeContent(content); + return encodeContent(HuaShengProtocolDecoder.MSG_SET_REQ, content); + case Command.TYPE_OUTPUT_CONTROL: + /* +0x01: Lock the relay1; //relay on +0x02: Unlock the relay1; //relay off +0x03: Lock the relay2; //relay2 on +0x04: Unlock the relay2; //relay2 off +0x05: Lock the relay3; //relay3 on +0x06: Unlock the relay3; //realy3 off + */ + content.writeByte( + (command.getInteger(Command.KEY_INDEX) - 1) * 2 + + (2 - command.getInteger(Command.KEY_DATA))); + return encodeContent(HuaShengProtocolDecoder.MSG_CTRL_REQ, content); case Command.TYPE_ALARM_ARM: case Command.TYPE_ALARM_DISARM: content.writeShort(0x0001); content.writeShort(5); // length content.writeByte(command.getType().equals(Command.TYPE_ALARM_ARM) ? 1 : 0); + return encodeContent(HuaShengProtocolDecoder.MSG_SET_REQ, content); case Command.TYPE_SET_SPEED_LIMIT: content.writeShort(0x0004); content.writeShort(6); // length content.writeShort(command.getInteger(Command.KEY_DATA)); - return encodeContent(content); + return encodeContent(HuaShengProtocolDecoder.MSG_SET_REQ, content); default: return null; } diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java index b44f6e89c..c320d4aa9 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolEncoderTest.java @@ -11,7 +11,17 @@ public class HuaShengProtocolEncoderTest extends ProtocolTest { var encoder = inject(new HuaShengProtocolEncoder(null)); - Command command = new Command(); + Command command; + + command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_OUTPUT_CONTROL); + command.set(Command.KEY_INDEX, 1); + command.set(Command.KEY_DATA, "1"); + + verifyCommand(encoder, command, binary("c00000000daa1600000000000101c0")); + + command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); command.set(Command.KEY_FREQUENCY, 60); -- cgit v1.2.3 From 074ed6014cc7e243ce907052dc86444c0d23ccdd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Mar 2023 09:10:53 -0700 Subject: Handle Traccar push errors --- .../traccar/notificators/NotificatorTraccar.java | 60 +++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index e32229506..fb9632ad0 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -16,23 +16,41 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; +import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; +import javax.json.JsonObject; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; @Singleton public class NotificatorTraccar implements Notificator { + private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorTraccar.class); + private final NotificationFormatter notificationFormatter; private final Client client; + private final Storage storage; + private final CacheManager cacheManager; private final String url; private final String key; @@ -54,9 +72,13 @@ public class NotificatorTraccar implements Notificator { } @Inject - public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { + public NotificatorTraccar( + Config config, NotificationFormatter notificationFormatter, Client client, + Storage storage, CacheManager cacheManager) { this.notificationFormatter = notificationFormatter; this.client = client; + this.storage = storage; + this.cacheManager = cacheManager; this.url = "https://www.traccar.org/push/"; this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); } @@ -72,11 +94,45 @@ public class NotificatorTraccar implements Notificator { item.body = shortMessage.getBody(); item.sound = "default"; + String[] tokenArray = user.getString("notificationTokens").split("[, ]"); + List registrationTokens = new ArrayList<>(Arrays.asList(tokenArray)); + Message message = new Message(); message.tokens = user.getString("notificationTokens").split("[, ]"); message.notification = item; - client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + var request = client.target(url).request().header("Authorization", "key=" + key); + try (Response result = request.post(Entity.json(message))) { + var json = result.readEntity(JsonObject.class); + List failedTokens = new LinkedList<>(); + var responses = json.getJsonArray("responses"); + for (int i = 0; i < responses.size(); i++) { + var response = responses.getJsonObject(i); + if (!response.getBoolean("success")) { + var error = response.getJsonObject("error"); + String errorCode = error.getString("code"); + if (errorCode.equals("messaging/invalid-argument") + || errorCode.equals("messaging/registration-token-not-registered")) { + failedTokens.add(registrationTokens.get(i)); + } + LOGGER.warn("Push user {} error - {}", user.getId(), error.getString("message")); + } + } + if (!failedTokens.isEmpty()) { + registrationTokens.removeAll(failedTokens); + if (registrationTokens.isEmpty()) { + user.getAttributes().remove("notificationTokens"); + } else { + user.set("notificationTokens", String.join(",", registrationTokens)); + } + storage.updateObject(user, new Request( + new Columns.Include("attributes"), + new Condition.Equals("id", user.getId()))); + cacheManager.updateOrInvalidate(true, user); + } + } catch (StorageException e) { + LOGGER.warn("Push error", e); + } } } -- cgit v1.2.3 From a91696336f2ed1fa38e3a945e77857e8e8f98461 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Fri, 31 Mar 2023 11:14:55 +0000 Subject: permission-check-fixed --- src/main/java/org/traccar/api/resource/PermissionsResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index d35cb98bb..f02c5d426 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -48,7 +48,7 @@ public class PermissionsResource extends BaseResource { private void checkPermission(Permission permission) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); - permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); + permissionsService.checkPermission(permission.getPropertyClass(), getUserId(), permission.getPropertyId()); } } -- cgit v1.2.3 From 5c26f25b3b0afc509c76bfc4a111dbc383efee26 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 31 Mar 2023 17:26:13 -0700 Subject: Multiple battery levels --- .../org/traccar/protocol/MeitrackProtocolDecoder.java | 15 +++++++-------- .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 4 ++++ 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 3f1f7f506..0f0d22021 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -554,15 +554,14 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(length - 2); break; case 0xFEA8: - if (buf.readUnsignedByte() > 0) { - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - } else { - buf.readUnsignedByte(); + for (int k = 1; k <= 3; k++) { + if (buf.readUnsignedByte() > 0) { + String key = k == 1 ? Position.KEY_BATTERY_LEVEL : "battery" + k + "Level"; + position.set(key, buf.readUnsignedByte()); + } else { + buf.readUnsignedByte(); + } } - buf.readUnsignedByte(); // battery 2 status - buf.readUnsignedByte(); // battery 2 level - buf.readUnsignedByte(); // battery 3 status - buf.readUnsignedByte(); // battery 3 level buf.readUnsignedByte(); // battery alert break; default: diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 1697fc920..8d2aee501 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "2424683136342C3836363334343035333039353238322C4343452C000000000100820018000505000600070B14001500080800000900000A00000B00001606001A0000402300FE90000006022E79570103E55CCC0604E1FDB32B0CC32C00000D58EB02001C01000000050E0CCC010000B627BF11000000004B1001010D475052532847534D2039303029FEA50601FFFFFF7FFFFEA80701010258023800FEB20501010000002A41360D0A"), + "battery2Level", 88); + verifyAttribute(decoder, binary( "2424593434312c3836353431333035303839313733372c4343452c00000000030088001800050501061607191400150008080000098e000a05000b0c001608001a0000402300fe9000000602c3fe5ffe03e22a1f0904e6688d2b0cd94002000d5f6f03001c01000000050e0cf901010032700298c80899ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb205010000000083001700050501061607191400150008080000098e000a05000b0c001608001a0000405100fe9000000502c3fe5ffe03e22a1f0904e6688d2b0cd94002000d606f0300050e0cf901010032700298c80899ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb205010000000088001800050501061607151400150008080000098e000a05000b0c001607001a0000402300fe9000000602c3fe5ffe03e22a1f0904f0688d2b0cd94002000d696f03001c01000000050e0cf901010032700298c80897ff4b16010113464444204c5445284c54452042414e44203329fea50601ffffff7ffffea807024d0000000000feb20501000000002a36320d0a"), Position.KEY_BATTERY_LEVEL, 77); -- cgit v1.2.3 From 836fb2221dedae55c3f8457f35294b3753f095c8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 31 Mar 2023 17:48:05 -0700 Subject: Additional HHD parameters --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 5e73967d5..f13299169 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -333,9 +333,16 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // power level position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; + case 0x60: + position.set(Position.KEY_EVENT, buf.readUnsignedShort()); + buf.skipBytes(length - 2); + break; case 0x61: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); break; + case 0x69: + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + break; case 0x80: position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); break; -- cgit v1.2.3 From 21ccdb1234407fb17f7b96245fb7aab770fa3cbd Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 1 Apr 2023 16:48:50 +0100 Subject: Add OIDC config keys --- src/main/java/org/traccar/config/Keys.java | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index c207efb1e..77aa9a635 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -610,6 +610,62 @@ public final class Keys { "ldap.adminGroup", List.of(KeyType.CONFIG)); + + /** + * OIDC enable. + */ + public static final ConfigKey OIDC_ENABLE = new BooleanConfigKey( + "oidc.enable", + List.of(KeyType.CONFIG)); + + /** + * Force OIDC authentication. + */ + public static final ConfigKey OIDC_FORCE = new BooleanConfigKey( + "oidc.force", + List.of(KeyType.CONFIG)); + + /** + * OIDC Client ID. + */ + public static final ConfigKey OIDC_CLIENTID = new StringConfigKey( + "oidc.clientId", + List.of(KeyType.CONFIG)); + + /** + * OIDC Client Secret. + */ + public static final ConfigKey OIDC_CLIENTSECRET = new StringConfigKey( + "oidc.clientSecret", + List.of(KeyType.CONFIG)); + + /** + * OIDC Authorization URL. + */ + public static final ConfigKey OIDC_AUTHURL = new StringConfigKey( + "oidc.authUrl", + List.of(KeyType.CONFIG)); + /** + * OIDC Token URL. + */ + public static final ConfigKey OIDC_TOKENURL = new StringConfigKey( + "oidc.tokenUrl", + List.of(KeyType.CONFIG)); + + /** + * OIDC User Info URL. + */ + public static final ConfigKey OIDC_USERINFOURL = new StringConfigKey( + "oidc.userInfoUrl", + List.of(KeyType.CONFIG)); + + /** + * OIDC group to grant admin access. + */ + public static final ConfigKey OIDC_ADMINGROUP = new StringConfigKey( + "oidc.adminGroup", + List.of(KeyType.CONFIG)); + /** * If no data is reported by a device for the given amount of time, status changes from online to unknown. Value is * in seconds. Default timeout is 10 minutes. -- cgit v1.2.3 From 1edce2477fde4ef8b626cf51ea175f86f63dd308 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 1 Apr 2023 17:08:55 +0100 Subject: Create OIDC class and add provider to MainModule --- src/main/java/org/traccar/MainModule.java | 10 +++++ .../org/traccar/api/security/OpenIDProvider.java | 44 ++++++++++++++++++++++ src/main/java/org/traccar/config/Keys.java | 4 +- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/traccar/api/security/OpenIDProvider.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 663747de1..417844f50 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -87,6 +87,7 @@ import org.traccar.storage.DatabaseStorage; import org.traccar.storage.MemoryStorage; import org.traccar.storage.Storage; import org.traccar.web.WebServer; +import org.traccar.api.security.OpenIDProvider; import javax.annotation.Nullable; import javax.inject.Singleton; @@ -169,6 +170,15 @@ public class MainModule extends AbstractModule { } return null; } + + @Singleton + @Provides + public static OpenIDProvider provideOpenIDProvider(Config config) { + if (config.getBoolean(Keys.OIDC_ENABLE)) { + return new OpenIDProvider(config); + } + return null; + } @Provides public static WebServer provideWebServer(Injector injector, Config config) { diff --git a/src/main/java/org/traccar/api/security/OpenIDProvider.java b/src/main/java/org/traccar/api/security/OpenIDProvider.java new file mode 100644 index 000000000..4eaf9ac21 --- /dev/null +++ b/src/main/java/org/traccar/api/security/OpenIDProvider.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017 - 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.api.security; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.User; + +public class OpenIDProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(OpenIDProvider.class); + + private final Boolean force; + private final String clientId; + private final String authUrl; + private final String tokenUrl; + private final String userInfoUrl; + private final String adminGroup; + + public OpenIDProvider(Config config) { + force = config.getBoolean(Keys.OIDC_FORCE); + clientId = config.getString(Keys.OIDC_CLIENTID); + authUrl = config.getString(Keys.OIDC_AUTHURL); + tokenUrl = config.getString(Keys.OIDC_TOKENURL); + userInfoUrl = config.getString(Keys.OIDC_USERINFOURL); + adminGroup = config.getString(Keys.OIDC_ADMINGROUP); + } + +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 77aa9a635..ace4c36af 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -614,14 +614,14 @@ public final class Keys { /** * OIDC enable. */ - public static final ConfigKey OIDC_ENABLE = new BooleanConfigKey( + public static final ConfigKey OIDC_ENABLE = new BooleanConfigKey( "oidc.enable", List.of(KeyType.CONFIG)); /** * Force OIDC authentication. */ - public static final ConfigKey OIDC_FORCE = new BooleanConfigKey( + public static final ConfigKey OIDC_FORCE = new BooleanConfigKey( "oidc.force", List.of(KeyType.CONFIG)); -- cgit v1.2.3 From f8339b4ca0ca7440854f759b32b821afe19f458b Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 1 Apr 2023 22:07:42 +0100 Subject: Add user lookup method --- src/main/java/org/traccar/api/security/LoginService.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 88bafcfb5..3d4f42b20 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -89,6 +89,19 @@ public class LoginService { return null; } + public User lookup(String email) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.All(), + new Condition.Equals("email", email))); + + if (user != null) { + checkUserEnabled(user); + return user; + } + + return null; + } + private void checkUserEnabled(User user) throws SecurityException { if (user == null) { throw new SecurityException("Unknown account"); -- cgit v1.2.3 From 92ebe0adba132bed5499bc1624620afeea34e347 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 1 Apr 2023 22:41:36 +0100 Subject: Initial implementation --- src/main/java/org/traccar/MainModule.java | 5 +- .../org/traccar/api/resource/SessionResource.java | 25 +++ .../org/traccar/api/security/OpenIDProvider.java | 224 +++++++++++++++++++-- 3 files changed, 239 insertions(+), 15 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 417844f50..7def97657 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -87,6 +87,7 @@ import org.traccar.storage.DatabaseStorage; import org.traccar.storage.MemoryStorage; import org.traccar.storage.Storage; import org.traccar.web.WebServer; +import org.traccar.api.security.LoginService; import org.traccar.api.security.OpenIDProvider; import javax.annotation.Nullable; @@ -173,9 +174,9 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static OpenIDProvider provideOpenIDProvider(Config config) { + public static OpenIDProvider provideOpenIDProvider(Config config, LoginService loginService, Storage storage) { if (config.getBoolean(Keys.OIDC_ENABLE)) { - return new OpenIDProvider(config); + return new OpenIDProvider(config, loginService, storage); } return null; } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index ff84c135f..ca9f37667 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; import org.traccar.api.security.LoginService; +import org.traccar.api.security.OpenIDProvider; import org.traccar.api.signature.TokenManager; import org.traccar.helper.DataConverter; import org.traccar.helper.LogAction; @@ -49,6 +50,7 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.util.Date; +import java.net.URI; @Path("session") @Produces(MediaType.APPLICATION_JSON) @@ -62,6 +64,9 @@ public class SessionResource extends BaseResource { @Inject private LoginService loginService; + @Inject + private OpenIDProvider openIdProvider; + @Inject private TokenManager tokenManager; @@ -160,4 +165,24 @@ public class SessionResource extends BaseResource { return tokenManager.generateToken(getUserId(), expiration); } + @PermitAll + @Path("openid/auth") + @GET + public Response openIdAuth() throws IOException { + return Response.seeOther( + openIdProvider.createAuthRequest() + ).build(); + } + + @PermitAll + @Path("openid/callback") + @GET + public Response requestToken() throws IOException, StorageException { + // Get full request URI + StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString()); + String queryString = request.getQueryString(); + String requestURI = requestURL.append('?').append(queryString).toString(); + + return openIdProvider.handleCallback(URI.create(requestURI), request); + } } diff --git a/src/main/java/org/traccar/api/security/OpenIDProvider.java b/src/main/java/org/traccar/api/security/OpenIDProvider.java index 4eaf9ac21..cd3fa4dde 100644 --- a/src/main/java/org/traccar/api/security/OpenIDProvider.java +++ b/src/main/java/org/traccar/api/security/OpenIDProvider.java @@ -15,30 +15,228 @@ */ package org.traccar.api.security; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.api.resource.SessionResource; import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Request; +import org.traccar.storage.query.Columns; +import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; -public class OpenIDProvider { +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Response; +import com.google.inject.Inject; + +import com.nimbusds.oauth2.sdk.http.HTTPResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCode; +import com.nimbusds.oauth2.sdk.ResponseType; +import com.nimbusds.oauth2.sdk.Scope; +import com.nimbusds.oauth2.sdk.AuthorizationGrant; +import com.nimbusds.oauth2.sdk.TokenRequest; +import com.nimbusds.oauth2.sdk.TokenResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; +import com.nimbusds.oauth2.sdk.ParseException; +import com.nimbusds.oauth2.sdk.AuthorizationResponse; +import com.nimbusds.oauth2.sdk.auth.Secret; +import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; +import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; +import com.nimbusds.oauth2.sdk.token.BearerAccessToken; +import com.nimbusds.oauth2.sdk.id.State; +import com.nimbusds.oauth2.sdk.id.ClientID; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; +import com.nimbusds.openid.connect.sdk.Nonce; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; +import com.nimbusds.openid.connect.sdk.UserInfoResponse; +import com.nimbusds.openid.connect.sdk.UserInfoRequest; +import com.nimbusds.openid.connect.sdk.AuthenticationRequest; - private static final Logger LOGGER = LoggerFactory.getLogger(OpenIDProvider.class); +import com.nimbusds.openid.connect.sdk.claims.UserInfo; +public class OpenIDProvider { private final Boolean force; - private final String clientId; - private final String authUrl; - private final String tokenUrl; - private final String userInfoUrl; + private final ClientID clientId; + private final Secret clientSecret; + private URI callbackUrl; + private URI authUrl; + private URI tokenUrl; + private URI userInfoUrl; + private URI baseUrl; private final String adminGroup; - public OpenIDProvider(Config config) { + private Config config; + private LoginService loginService; + private Storage storage; + + @Inject + public OpenIDProvider(Config config, LoginService loginService, Storage storage) { force = config.getBoolean(Keys.OIDC_FORCE); - clientId = config.getString(Keys.OIDC_CLIENTID); - authUrl = config.getString(Keys.OIDC_AUTHURL); - tokenUrl = config.getString(Keys.OIDC_TOKENURL); - userInfoUrl = config.getString(Keys.OIDC_USERINFOURL); + clientId = new ClientID(config.getString(Keys.OIDC_CLIENTID)); + clientSecret = new Secret(config.getString(Keys.OIDC_CLIENTSECRET)); + + this.config = config; + this.storage = storage; + this.loginService = loginService; + + try { + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + authUrl = new URI(config.getString(Keys.OIDC_AUTHURL, "")); + tokenUrl = new URI(config.getString(Keys.OIDC_TOKENURL, "")); + userInfoUrl = new URI(config.getString(Keys.OIDC_USERINFOURL, "")); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + } catch (URISyntaxException e) { + } + adminGroup = config.getString(Keys.OIDC_ADMINGROUP); } + public URI createAuthRequest() { + AuthenticationRequest request = new AuthenticationRequest.Builder( + new ResponseType("code"), + new Scope("openid", "profile", "email", "groups"), + this.clientId, + this.callbackUrl) + .endpointURI(this.authUrl) + .state(new State()) + .nonce(new Nonce()) + .build(); + + return request.toURI(); + } + + private OIDCTokenResponse getToken(AuthorizationCode code) { + // Credentials to authenticate us to the token endpoint + ClientAuthentication clientAuth = new ClientSecretBasic(this.clientId, this.clientSecret); + AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, this.callbackUrl); + + TokenRequest request = new TokenRequest(this.tokenUrl, clientAuth, codeGrant); + TokenResponse tokenResponse; + + try { + HTTPResponse tokenReq = request.toHTTPRequest().send(); + tokenResponse = OIDCTokenResponseParser.parse(tokenReq); + if (!tokenResponse.indicatesSuccess()) { + return null; + } + + return (OIDCTokenResponse) tokenResponse.toSuccessResponse(); + } catch (IOException e) { + return null; + } catch (ParseException e) { + return null; + } + } + + private AuthorizationCode parseCallback(URI requri) { + AuthorizationResponse response; + + try { + response = AuthorizationResponse.parse(requri); + } catch (ParseException e) { + return null; + } + + if (!response.indicatesSuccess()) { + return null; + } + + return response.toSuccessResponse().getAuthorizationCode(); + } + + private UserInfo getUserInfo(BearerAccessToken token) { + UserInfoResponse userInfoResponse; + + try { + HTTPResponse httpResponse = new UserInfoRequest(this.userInfoUrl, token) + .toHTTPRequest() + .send(); + + userInfoResponse = UserInfoResponse.parse(httpResponse); + } catch (IOException e) { + return null; + } catch (ParseException e) { + return null; + } + + if (!userInfoResponse.indicatesSuccess()) { + // User info request failed - usually from expiring + return null; + } + + return userInfoResponse.toSuccessResponse().getUserInfo(); + } + + private User createUser(String name, String email, Boolean administrator) throws StorageException { + User user = new User(); + + user.setName(name); + user.setEmail(email); + user.setFixedEmail(true); + user.setDeviceLimit(this.config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); + + int expirationDays = this.config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); + + if (expirationDays > 0) { + user.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); + } + + if (administrator) { + user.setAdministrator(true); + } + + user.setId(this.storage.addObject(user, new Request(new Columns.Exclude("id")))); + + return user; + } + + public Response handleCallback(URI requri, HttpServletRequest request) throws StorageException { + // Parse callback + AuthorizationCode authCode = this.parseCallback(requri); + + if (authCode == null) { + return Response.ok().entity("Callback parse fail").build(); + } + + // Get token from IDP + OIDCTokenResponse tokens = this.getToken(authCode); + + if (tokens == null) { + return Response.ok().entity("Token request failed").build(); + } + + BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); + + // Get user info from IDP + UserInfo idpUser = this.getUserInfo(bearerToken); + + if (idpUser == null) { + return Response.ok().entity("User info request failed").build(); + } + + String email = idpUser.getEmailAddress(); + String name = idpUser.getName(); + + // Check if user exists + User user = this.loginService.lookup(email); + + // If user does not exist, create one + if (user == null) { + List groups = idpUser.getStringListClaim("groups"); + Boolean administrator = groups.contains(this.adminGroup); + user = this.createUser(name, email, administrator); + } + + // Set user session and redirect to homepage + request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return Response.seeOther( + baseUrl).build(); + } } -- cgit v1.2.3 From 21abf0f8479c48d8b826dd861f8c1227e6a00e25 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 1 Apr 2023 22:53:34 +0100 Subject: Throw API error if oidc disabled --- src/main/java/org/traccar/api/resource/SessionResource.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index ca9f37667..515d7374a 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -169,6 +169,10 @@ public class SessionResource extends BaseResource { @Path("openid/auth") @GET public Response openIdAuth() throws IOException { + if (openIdProvider == null) { + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); + } + return Response.seeOther( openIdProvider.createAuthRequest() ).build(); @@ -178,6 +182,10 @@ public class SessionResource extends BaseResource { @Path("openid/callback") @GET public Response requestToken() throws IOException, StorageException { + if (openIdProvider == null) { + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); + } + // Get full request URI StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString()); String queryString = request.getQueryString(); -- cgit v1.2.3 From 040fa7c83b67b0c6541348c4ecd3979c7a80ebc5 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 1 Apr 2023 23:10:18 +0100 Subject: Expose OIDC state on /server endpoint --- .../java/org/traccar/api/security/OpenIDProvider.java | 2 +- src/main/java/org/traccar/model/Server.java | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/OpenIDProvider.java b/src/main/java/org/traccar/api/security/OpenIDProvider.java index cd3fa4dde..80d84dfbd 100644 --- a/src/main/java/org/traccar/api/security/OpenIDProvider.java +++ b/src/main/java/org/traccar/api/security/OpenIDProvider.java @@ -61,7 +61,7 @@ import com.nimbusds.openid.connect.sdk.AuthenticationRequest; import com.nimbusds.openid.connect.sdk.claims.UserInfo; public class OpenIDProvider { - private final Boolean force; + public final Boolean force; private final ClientID clientId; private final Secret clientSecret; private URI callbackUrl; diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 73645721b..4c6e10b5e 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -16,13 +16,16 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import org.traccar.Main; +import org.traccar.api.security.OpenIDProvider; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @StorageName("tc_servers") @JsonIgnoreProperties(ignoreUnknown = true) public class Server extends ExtendedModel implements UserRestrictions { - + private boolean registration; public boolean getRegistration() { @@ -261,4 +264,15 @@ public class Server extends ExtendedModel implements UserRestrictions { this.newServer = newServer; } + @QueryIgnore + public boolean getOidcEnabled() { + OpenIDProvider oidc = Main.getInjector().getInstance(OpenIDProvider.class); + return oidc != null; + } + + @QueryIgnore + public boolean getOidcForce() { + OpenIDProvider oidc = Main.getInjector().getInstance(OpenIDProvider.class); + return oidc != null && oidc.force; + } } -- cgit v1.2.3 From 2cc1cb3c7530fdabb750a9e0b5cc26e3e2286185 Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 2 Apr 2023 13:51:46 +0100 Subject: Add better error handling --- .../java/org/traccar/api/security/OpenIDProvider.java | 15 +++++++++------ swagger.json | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/OpenIDProvider.java b/src/main/java/org/traccar/api/security/OpenIDProvider.java index 80d84dfbd..1e18fde43 100644 --- a/src/main/java/org/traccar/api/security/OpenIDProvider.java +++ b/src/main/java/org/traccar/api/security/OpenIDProvider.java @@ -32,6 +32,7 @@ import java.util.Date; import java.util.List; import java.io.IOException; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import com.google.inject.Inject; @@ -43,6 +44,7 @@ import com.nimbusds.oauth2.sdk.AuthorizationGrant; import com.nimbusds.oauth2.sdk.TokenRequest; import com.nimbusds.oauth2.sdk.TokenResponse; import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; +import com.nimbusds.oauth2.sdk.AuthorizationErrorResponse; import com.nimbusds.oauth2.sdk.ParseException; import com.nimbusds.oauth2.sdk.AuthorizationResponse; import com.nimbusds.oauth2.sdk.auth.Secret; @@ -134,7 +136,7 @@ public class OpenIDProvider { } } - private AuthorizationCode parseCallback(URI requri) { + private AuthorizationCode parseCallback(URI requri) throws WebApplicationException { AuthorizationResponse response; try { @@ -144,7 +146,8 @@ public class OpenIDProvider { } if (!response.indicatesSuccess()) { - return null; + AuthorizationErrorResponse error = response.toErrorResponse(); + throw new WebApplicationException(Response.status(403).entity(error.getErrorObject().getDescription()).build()); } return response.toSuccessResponse().getAuthorizationCode(); @@ -196,19 +199,19 @@ public class OpenIDProvider { return user; } - public Response handleCallback(URI requri, HttpServletRequest request) throws StorageException { + public Response handleCallback(URI requri, HttpServletRequest request) throws StorageException, WebApplicationException { // Parse callback AuthorizationCode authCode = this.parseCallback(requri); if (authCode == null) { - return Response.ok().entity("Callback parse fail").build(); + return Response.status(403).entity( "Invalid OpenID Connect callback.").build(); } // Get token from IDP OIDCTokenResponse tokens = this.getToken(authCode); if (tokens == null) { - return Response.ok().entity("Token request failed").build(); + return Response.status(403).entity("Unable to authenticate with the OpenID Connect provider. Please try again.").build(); } BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); @@ -217,7 +220,7 @@ public class OpenIDProvider { UserInfo idpUser = this.getUserInfo(bearerToken); if (idpUser == null) { - return Response.ok().entity("User info request failed").build(); + return Response.status(500).entity("Failed to access OpenID Connect user info endpoint. Please contact your administrator.").build(); } String email = idpUser.getEmailAddress(); diff --git a/swagger.json b/swagger.json index 6a8bc91f6..8968db4eb 100644 --- a/swagger.json +++ b/swagger.json @@ -1027,6 +1027,10 @@ "303": { "description": "Redirect to OpenID Connect identity provider", "content": { } + }, + "404": { + "description": "OpenID Connect disabled", + "content": { } } } } @@ -1043,11 +1047,19 @@ ], "responses": { "303": { - "description": "Redirect to homepage", + "description": "Successful authentication, redirect to homepage", + "content": { } + }, + "403": { + "description": "Invalid callback or negative response from identity provider", "content": { } }, "404": { - "description": "Invalid callback", + "description": "OpenID Connect disabled", + "content": { } + }, + "500": { + "description": "Other OpenID Connect error", "content": { } } } -- cgit v1.2.3 From faf5567add4cf343cc38b3c7dcb297c7cbed88bc Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 12:12:38 +0100 Subject: First pass --- src/main/java/org/traccar/MainModule.java | 8 +- .../org/traccar/api/resource/ServerResource.java | 7 + .../org/traccar/api/resource/SessionResource.java | 26 +-- .../org/traccar/api/security/LoginService.java | 17 +- .../org/traccar/api/security/OpenIDProvider.java | 245 --------------------- src/main/java/org/traccar/config/Keys.java | 68 +++--- .../java/org/traccar/database/OpenIdProvider.java | 183 +++++++++++++++ src/main/java/org/traccar/model/Server.java | 28 ++- 8 files changed, 270 insertions(+), 312 deletions(-) delete mode 100644 src/main/java/org/traccar/api/security/OpenIDProvider.java create mode 100644 src/main/java/org/traccar/database/OpenIdProvider.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 7def97657..7b06b4840 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -33,6 +33,7 @@ import org.traccar.broadcast.NullBroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.database.OpenIdProvider; import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; @@ -88,7 +89,6 @@ import org.traccar.storage.MemoryStorage; import org.traccar.storage.Storage; import org.traccar.web.WebServer; import org.traccar.api.security.LoginService; -import org.traccar.api.security.OpenIDProvider; import javax.annotation.Nullable; import javax.inject.Singleton; @@ -174,9 +174,9 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static OpenIDProvider provideOpenIDProvider(Config config, LoginService loginService, Storage storage) { - if (config.getBoolean(Keys.OIDC_ENABLE)) { - return new OpenIDProvider(config, loginService, storage); + public static OpenIdProvider provideOpenIDProvider(Config config, LoginService loginService) { + if (config.hasKey(Keys.OPENID_CLIENTID)) { + return new OpenIdProvider(config, loginService); } return null; } diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 4b7ee9189..9b4d82a66 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -16,6 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.database.OpenIdProvider; import org.traccar.helper.model.UserUtil; import org.traccar.mail.MailManager; import org.traccar.geocoder.Geocoder; @@ -55,6 +56,10 @@ public class ServerResource extends BaseResource { @Inject private MailManager mailManager; + @Inject + @Nullable + private OpenIdProvider openIdProvider; + @Inject @Nullable private Geocoder geocoder; @@ -65,6 +70,8 @@ public class ServerResource extends BaseResource { Server server = storage.getObject(Server.class, new Request(new Columns.All())); server.setEmailEnabled(mailManager.getEmailEnabled()); server.setGeocoderEnabled(geocoder != null); + server.setOpenIdEnabled(openIdProvider != null); + server.setOpenIdForce(openIdProvider != null && openIdProvider.force); User user = permissionsService.getUser(getUserId()); if (user != null) { if (user.getAdministrator()) { diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 515d7374a..3de20b8c7 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -17,8 +17,8 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; import org.traccar.api.security.LoginService; -import org.traccar.api.security.OpenIDProvider; import org.traccar.api.signature.TokenManager; +import org.traccar.database.OpenIdProvider; import org.traccar.helper.DataConverter; import org.traccar.helper.LogAction; import org.traccar.helper.ServletHelper; @@ -28,6 +28,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import com.nimbusds.oauth2.sdk.ParseException; import javax.annotation.security.PermitAll; import javax.inject.Inject; import javax.servlet.http.Cookie; @@ -65,7 +66,7 @@ public class SessionResource extends BaseResource { private LoginService loginService; @Inject - private OpenIDProvider openIdProvider; + private OpenIdProvider openIdProvider; @Inject private TokenManager tokenManager; @@ -169,28 +170,17 @@ public class SessionResource extends BaseResource { @Path("openid/auth") @GET public Response openIdAuth() throws IOException { - if (openIdProvider == null) { - throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); - } - - return Response.seeOther( - openIdProvider.createAuthRequest() - ).build(); + return Response.seeOther(openIdProvider.createAuthUri()).build(); } @PermitAll @Path("openid/callback") @GET - public Response requestToken() throws IOException, StorageException { - if (openIdProvider == null) { - throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); - } - - // Get full request URI - StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString()); + public Response requestToken() throws IOException, StorageException, ParseException { + StringBuilder requestUrl = new StringBuilder(request.getRequestURL().toString()); String queryString = request.getQueryString(); - String requestURI = requestURL.append('?').append(queryString).toString(); + String requestUri = requestUrl.append('?').append(queryString).toString(); - return openIdProvider.handleCallback(URI.create(requestURI), request); + return openIdProvider.handleCallback(URI.create(requestUri), request); } } diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 3d4f42b20..7b51667c8 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -89,17 +89,24 @@ public class LoginService { return null; } - public User lookup(String email) throws StorageException { + public User login(String email, String name, Boolean administrator) throws StorageException { User user = storage.getObject(User.class, new Request( - new Columns.All(), - new Condition.Equals("email", email))); + new Columns.All(), + new Condition.Equals("email", email))); if (user != null) { checkUserEnabled(user); return user; + } else { + user = new User(); + user.setName(name); + user.setEmail(email); + user.setFixedEmail(true); + user.setAdministrator(administrator); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; } - - return null; } private void checkUserEnabled(User user) throws SecurityException { diff --git a/src/main/java/org/traccar/api/security/OpenIDProvider.java b/src/main/java/org/traccar/api/security/OpenIDProvider.java deleted file mode 100644 index 1e18fde43..000000000 --- a/src/main/java/org/traccar/api/security/OpenIDProvider.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2017 - 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.api.security; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.api.resource.SessionResource; -import org.traccar.model.User; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Request; -import org.traccar.storage.query.Columns; -import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Date; -import java.util.List; -import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; -import com.google.inject.Inject; - -import com.nimbusds.oauth2.sdk.http.HTTPResponse; -import com.nimbusds.oauth2.sdk.AuthorizationCode; -import com.nimbusds.oauth2.sdk.ResponseType; -import com.nimbusds.oauth2.sdk.Scope; -import com.nimbusds.oauth2.sdk.AuthorizationGrant; -import com.nimbusds.oauth2.sdk.TokenRequest; -import com.nimbusds.oauth2.sdk.TokenResponse; -import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; -import com.nimbusds.oauth2.sdk.AuthorizationErrorResponse; -import com.nimbusds.oauth2.sdk.ParseException; -import com.nimbusds.oauth2.sdk.AuthorizationResponse; -import com.nimbusds.oauth2.sdk.auth.Secret; -import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; -import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; -import com.nimbusds.oauth2.sdk.token.BearerAccessToken; -import com.nimbusds.oauth2.sdk.id.State; -import com.nimbusds.oauth2.sdk.id.ClientID; -import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; -import com.nimbusds.openid.connect.sdk.Nonce; -import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; -import com.nimbusds.openid.connect.sdk.UserInfoResponse; -import com.nimbusds.openid.connect.sdk.UserInfoRequest; -import com.nimbusds.openid.connect.sdk.AuthenticationRequest; - -import com.nimbusds.openid.connect.sdk.claims.UserInfo; - -public class OpenIDProvider { - public final Boolean force; - private final ClientID clientId; - private final Secret clientSecret; - private URI callbackUrl; - private URI authUrl; - private URI tokenUrl; - private URI userInfoUrl; - private URI baseUrl; - private final String adminGroup; - - private Config config; - private LoginService loginService; - private Storage storage; - - @Inject - public OpenIDProvider(Config config, LoginService loginService, Storage storage) { - force = config.getBoolean(Keys.OIDC_FORCE); - clientId = new ClientID(config.getString(Keys.OIDC_CLIENTID)); - clientSecret = new Secret(config.getString(Keys.OIDC_CLIENTSECRET)); - - this.config = config; - this.storage = storage; - this.loginService = loginService; - - try { - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - authUrl = new URI(config.getString(Keys.OIDC_AUTHURL, "")); - tokenUrl = new URI(config.getString(Keys.OIDC_TOKENURL, "")); - userInfoUrl = new URI(config.getString(Keys.OIDC_USERINFOURL, "")); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - } catch (URISyntaxException e) { - } - - adminGroup = config.getString(Keys.OIDC_ADMINGROUP); - } - - public URI createAuthRequest() { - AuthenticationRequest request = new AuthenticationRequest.Builder( - new ResponseType("code"), - new Scope("openid", "profile", "email", "groups"), - this.clientId, - this.callbackUrl) - .endpointURI(this.authUrl) - .state(new State()) - .nonce(new Nonce()) - .build(); - - return request.toURI(); - } - - private OIDCTokenResponse getToken(AuthorizationCode code) { - // Credentials to authenticate us to the token endpoint - ClientAuthentication clientAuth = new ClientSecretBasic(this.clientId, this.clientSecret); - AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, this.callbackUrl); - - TokenRequest request = new TokenRequest(this.tokenUrl, clientAuth, codeGrant); - TokenResponse tokenResponse; - - try { - HTTPResponse tokenReq = request.toHTTPRequest().send(); - tokenResponse = OIDCTokenResponseParser.parse(tokenReq); - if (!tokenResponse.indicatesSuccess()) { - return null; - } - - return (OIDCTokenResponse) tokenResponse.toSuccessResponse(); - } catch (IOException e) { - return null; - } catch (ParseException e) { - return null; - } - } - - private AuthorizationCode parseCallback(URI requri) throws WebApplicationException { - AuthorizationResponse response; - - try { - response = AuthorizationResponse.parse(requri); - } catch (ParseException e) { - return null; - } - - if (!response.indicatesSuccess()) { - AuthorizationErrorResponse error = response.toErrorResponse(); - throw new WebApplicationException(Response.status(403).entity(error.getErrorObject().getDescription()).build()); - } - - return response.toSuccessResponse().getAuthorizationCode(); - } - - private UserInfo getUserInfo(BearerAccessToken token) { - UserInfoResponse userInfoResponse; - - try { - HTTPResponse httpResponse = new UserInfoRequest(this.userInfoUrl, token) - .toHTTPRequest() - .send(); - - userInfoResponse = UserInfoResponse.parse(httpResponse); - } catch (IOException e) { - return null; - } catch (ParseException e) { - return null; - } - - if (!userInfoResponse.indicatesSuccess()) { - // User info request failed - usually from expiring - return null; - } - - return userInfoResponse.toSuccessResponse().getUserInfo(); - } - - private User createUser(String name, String email, Boolean administrator) throws StorageException { - User user = new User(); - - user.setName(name); - user.setEmail(email); - user.setFixedEmail(true); - user.setDeviceLimit(this.config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); - - int expirationDays = this.config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); - - if (expirationDays > 0) { - user.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); - } - - if (administrator) { - user.setAdministrator(true); - } - - user.setId(this.storage.addObject(user, new Request(new Columns.Exclude("id")))); - - return user; - } - - public Response handleCallback(URI requri, HttpServletRequest request) throws StorageException, WebApplicationException { - // Parse callback - AuthorizationCode authCode = this.parseCallback(requri); - - if (authCode == null) { - return Response.status(403).entity( "Invalid OpenID Connect callback.").build(); - } - - // Get token from IDP - OIDCTokenResponse tokens = this.getToken(authCode); - - if (tokens == null) { - return Response.status(403).entity("Unable to authenticate with the OpenID Connect provider. Please try again.").build(); - } - - BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); - - // Get user info from IDP - UserInfo idpUser = this.getUserInfo(bearerToken); - - if (idpUser == null) { - return Response.status(500).entity("Failed to access OpenID Connect user info endpoint. Please contact your administrator.").build(); - } - - String email = idpUser.getEmailAddress(); - String name = idpUser.getName(); - - // Check if user exists - User user = this.loginService.lookup(email); - - // If user does not exist, create one - if (user == null) { - List groups = idpUser.getStringListClaim("groups"); - Boolean administrator = groups.contains(this.adminGroup); - user = this.createUser(name, email, administrator); - } - - // Set user session and redirect to homepage - request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return Response.seeOther( - baseUrl).build(); - } -} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ace4c36af..a666667d4 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -610,61 +610,67 @@ public final class Keys { "ldap.adminGroup", List.of(KeyType.CONFIG)); - /** - * OIDC enable. + * Force OpenID Connect authentication. When enabled, the Traccar login page will be skipped + * and users are redirected to the OpenID Connect provider. */ - public static final ConfigKey OIDC_ENABLE = new BooleanConfigKey( - "oidc.enable", + public static final ConfigKey OPENID_FORCE = new BooleanConfigKey( + "openid.force", List.of(KeyType.CONFIG)); /** - * Force OIDC authentication. + * OpenID Connect Client ID. + * This is a unique ID assigned to each application you register with your identity provider. + * Required to enable SSO. */ - public static final ConfigKey OIDC_FORCE = new BooleanConfigKey( - "oidc.force", + public static final ConfigKey OPENID_CLIENTID = new StringConfigKey( + "openid.clientId", List.of(KeyType.CONFIG)); /** - * OIDC Client ID. + * OpenID Connect Client Secret. + * This is a secret assigned to each application you register with your identity provider. + * Required to enable SSO. */ - public static final ConfigKey OIDC_CLIENTID = new StringConfigKey( - "oidc.clientId", + public static final ConfigKey OPENID_CLIENTSECRET = new StringConfigKey( + "openid.clientSecret", List.of(KeyType.CONFIG)); /** - * OIDC Client Secret. + * OpenID Connect Authorization URL. + * This can usually be found in the documentation of your identity provider or by using the well-known + * configuration endpoint, eg. https://auth.example.com//.well-known/openid-configuration + * Required to enable SSO. */ - public static final ConfigKey OIDC_CLIENTSECRET = new StringConfigKey( - "oidc.clientSecret", + public static final ConfigKey OPENID_AUTHURL = new StringConfigKey( + "openid.authUrl", List.of(KeyType.CONFIG)); - /** - * OIDC Authorization URL. + * OpenID Connect Token URL. + * This can be found in the same ways at openid.authUrl. + * Required to enable SSO. */ - public static final ConfigKey OIDC_AUTHURL = new StringConfigKey( - "oidc.authUrl", - List.of(KeyType.CONFIG)); - /** - * OIDC Token URL. - */ - public static final ConfigKey OIDC_TOKENURL = new StringConfigKey( - "oidc.tokenUrl", + public static final ConfigKey OPENID_TOKENURL = new StringConfigKey( + "openid.tokenUrl", List.of(KeyType.CONFIG)); /** - * OIDC User Info URL. + * OpenID Connect User Info URL. + * This can be found in the same ways at openid.authUrl. + * Required to enable SSO. */ - public static final ConfigKey OIDC_USERINFOURL = new StringConfigKey( - "oidc.userInfoUrl", + public static final ConfigKey OPENID_USERINFOURL = new StringConfigKey( + "openid.userInfoUrl", List.of(KeyType.CONFIG)); /** - * OIDC group to grant admin access. + * OpenID Connect group to grant admin access. + * Defaults to admins. */ - public static final ConfigKey OIDC_ADMINGROUP = new StringConfigKey( - "oidc.adminGroup", - List.of(KeyType.CONFIG)); + public static final ConfigKey OPENID_ADMINGROUP = new StringConfigKey( + "openid.adminGroup", + List.of(KeyType.CONFIG), + "admins"); /** * If no data is reported by a device for the given amount of time, status changes from online to unknown. Value is @@ -1629,7 +1635,7 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Public URL for the web app. Used for notification and report link. + * Public URL for the web app. Used for notification, report link and OpenID Connect. * If not provided, Traccar will attempt to get a URL from the server IP address, but it might be a local address. */ public static final ConfigKey WEB_URL = new StringConfigKey( diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java new file mode 100644 index 000000000..fc1409d14 --- /dev/null +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -0,0 +1,183 @@ +/* + * Copyright 2023 Daniel Raper (me@danr.uk) + * + * 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.database; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.api.resource.SessionResource; +import org.traccar.api.security.LoginService; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; + +import java.net.URI; +import java.net.URISyntaxException; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import com.google.inject.Inject; + +import com.nimbusds.oauth2.sdk.http.HTTPResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCode; +import com.nimbusds.oauth2.sdk.ResponseType; +import com.nimbusds.oauth2.sdk.Scope; +import com.nimbusds.oauth2.sdk.AuthorizationGrant; +import com.nimbusds.oauth2.sdk.TokenRequest; +import com.nimbusds.oauth2.sdk.TokenResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; +import com.nimbusds.oauth2.sdk.AuthorizationErrorResponse; +import com.nimbusds.oauth2.sdk.ParseException; +import com.nimbusds.oauth2.sdk.AuthorizationResponse; +import com.nimbusds.oauth2.sdk.auth.Secret; +import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; +import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; +import com.nimbusds.oauth2.sdk.token.BearerAccessToken; +import com.nimbusds.oauth2.sdk.id.State; +import com.nimbusds.oauth2.sdk.id.ClientID; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; +import com.nimbusds.openid.connect.sdk.Nonce; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; +import com.nimbusds.openid.connect.sdk.UserInfoResponse; +import com.nimbusds.openid.connect.sdk.UserInfoRequest; +import com.nimbusds.openid.connect.sdk.AuthenticationRequest; + +import com.nimbusds.openid.connect.sdk.claims.UserInfo; + +public class OpenIdProvider { + public final Boolean force; + private final ClientID clientId; + private final Secret clientSecret; + private URI callbackUrl; + private URI authUrl; + private URI tokenUrl; + private URI userInfoUrl; + private URI baseUrl; + private final String adminGroup; + + private LoginService loginService; + + @Inject + public OpenIdProvider(Config config, LoginService loginService) { + force = config.getBoolean(Keys.OPENID_FORCE); + clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); + clientSecret = new Secret(config.getString(Keys.OPENID_CLIENTSECRET)); + + this.loginService = loginService; + + try { + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, "")); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + } catch (URISyntaxException e) { + } + + adminGroup = config.getString(Keys.OPENID_ADMINGROUP); + } + + public URI createAuthUri() { + AuthenticationRequest request = new AuthenticationRequest.Builder( + new ResponseType("code"), + new Scope("openid", "profile", "email", "groups"), + clientId, + callbackUrl) + .endpointURI(authUrl) + .state(new State()) + .nonce(new Nonce()) + .build(); + + return request.toURI(); + } + + private OIDCTokenResponse getToken(AuthorizationCode code) { + // Credentials to authenticate us to the token endpoint + ClientAuthentication clientAuth = new ClientSecretBasic(clientId, clientSecret); + AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); + + TokenRequest request = new TokenRequest(tokenUrl, clientAuth, codeGrant); + TokenResponse tokenResponse; + + try { + HTTPResponse tokenReq = request.toHTTPRequest().send(); + tokenResponse = OIDCTokenResponseParser.parse(tokenReq); + if (!tokenResponse.indicatesSuccess()) { + return null; + } + + return (OIDCTokenResponse) tokenResponse.toSuccessResponse(); + } catch (IOException e) { + return null; + } catch (ParseException e) { + return null; + } + } + + private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException { + UserInfoResponse userInfoResponse; + + HTTPResponse httpResponse = new UserInfoRequest(userInfoUrl, token) + .toHTTPRequest() + .send(); + + userInfoResponse = UserInfoResponse.parse(httpResponse); + + if (!userInfoResponse.indicatesSuccess()) { + // User info request failed - usually from expiring + return null; + } + + return userInfoResponse.toSuccessResponse().getUserInfo(); + } + + public Response handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, WebApplicationException { + AuthorizationResponse response = AuthorizationResponse.parse(requestUri); + + if (!response.indicatesSuccess()) { + AuthorizationErrorResponse error = response.toErrorResponse(); + throw new WebApplicationException(Response.status(403).entity(error.getErrorObject().getDescription()).build()); + } + + AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); + + if (authCode == null) { + return Response.status(403).entity( "Invalid OpenID Connect callback.").build(); + } + + OIDCTokenResponse tokens = getToken(authCode); + + if (tokens == null) { + return Response.status(403).entity("Unable to authenticate with the OpenID Connect provider. Please try again.").build(); + } + + BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); + + UserInfo userInfo = getUserInfo(bearerToken); + + if (userInfo == null) { + return Response.status(500).entity("Failed to access OpenID Connect user info endpoint. Please contact your administrator.").build(); + } + + User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), userInfo.getStringListClaim("groups").contains(adminGroup)); + + request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return Response.seeOther( + baseUrl).build(); + } +} diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 4c6e10b5e..b790ca472 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -17,15 +17,13 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.traccar.Main; -import org.traccar.api.security.OpenIDProvider; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @StorageName("tc_servers") @JsonIgnoreProperties(ignoreUnknown = true) public class Server extends ExtendedModel implements UserRestrictions { - + private boolean registration; public boolean getRegistration() { @@ -264,15 +262,27 @@ public class Server extends ExtendedModel implements UserRestrictions { this.newServer = newServer; } + private boolean openIdEnabled; + + @QueryIgnore + public boolean getOpenIdEnabled() { + return openIdEnabled; + } + + @QueryIgnore + public void setOpenIdEnabled(boolean openIdEnabled) { + this.openIdEnabled = openIdEnabled; + } + + private boolean openIdForce; + @QueryIgnore - public boolean getOidcEnabled() { - OpenIDProvider oidc = Main.getInjector().getInstance(OpenIDProvider.class); - return oidc != null; + public boolean getOpenIdForce() { + return openIdForce; } @QueryIgnore - public boolean getOidcForce() { - OpenIDProvider oidc = Main.getInjector().getInstance(OpenIDProvider.class); - return oidc != null && oidc.force; + public void setOpenIdForce(boolean openIdForce) { + this.openIdForce = openIdForce; } } -- cgit v1.2.3 From 0fc695a4c1a09ef9d33ea2fd0658f6dece989381 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 12:58:26 +0100 Subject: Second pass --- build.gradle | 1 - .../org/traccar/api/resource/SessionResource.java | 4 +- .../java/org/traccar/database/OpenIdProvider.java | 75 +++++++++------------- traccar-web | 2 +- 4 files changed, 34 insertions(+), 48 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index ff5004c77..c29f3ba26 100644 --- a/build.gradle +++ b/build.gradle @@ -87,7 +87,6 @@ dependencies { implementation "redis.clients:jedis:4.3.1" implementation "com.google.firebase:firebase-admin:9.1.1" implementation "com.nimbusds:oauth2-oidc-sdk:10.7.1" - implementation "net.minidev:json-smart:2.4.10" testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" testImplementation "org.junit.jupiter:junit-jupiter-engine:$junitVersion" testImplementation "org.mockito:mockito-core:5.1.1" diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 3de20b8c7..a20e5f100 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -176,11 +176,11 @@ public class SessionResource extends BaseResource { @PermitAll @Path("openid/callback") @GET - public Response requestToken() throws IOException, StorageException, ParseException { + public Response requestToken() throws IOException, StorageException, ParseException, GeneralSecurityException { StringBuilder requestUrl = new StringBuilder(request.getRequestURL().toString()); String queryString = request.getQueryString(); String requestUri = requestUrl.append('?').append(queryString).toString(); - return openIdProvider.handleCallback(URI.create(requestUri), request); + return Response.seeOther(openIdProvider.handleCallback(URI.create(requestUri), request)).build(); } } diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index fc1409d14..6f44d0e80 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -26,11 +26,12 @@ import org.traccar.helper.ServletHelper; import java.net.URI; import java.net.URISyntaxException; +import java.security.GeneralSecurityException; import java.io.IOException; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; import com.google.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.nimbusds.oauth2.sdk.http.HTTPResponse; import com.nimbusds.oauth2.sdk.AuthorizationCode; @@ -40,7 +41,6 @@ import com.nimbusds.oauth2.sdk.AuthorizationGrant; import com.nimbusds.oauth2.sdk.TokenRequest; import com.nimbusds.oauth2.sdk.TokenResponse; import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; -import com.nimbusds.oauth2.sdk.AuthorizationErrorResponse; import com.nimbusds.oauth2.sdk.ParseException; import com.nimbusds.oauth2.sdk.AuthorizationResponse; import com.nimbusds.oauth2.sdk.auth.Secret; @@ -59,9 +59,11 @@ import com.nimbusds.openid.connect.sdk.AuthenticationRequest; import com.nimbusds.openid.connect.sdk.claims.UserInfo; public class OpenIdProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); + public final Boolean force; private final ClientID clientId; - private final Secret clientSecret; + private final ClientAuthentication clientAuth; private URI callbackUrl; private URI authUrl; private URI tokenUrl; @@ -72,12 +74,12 @@ public class OpenIdProvider { private LoginService loginService; @Inject - public OpenIdProvider(Config config, LoginService loginService) { + public OpenIdProvider(Config config, LoginService loginService) { + this.loginService = loginService; + force = config.getBoolean(Keys.OPENID_FORCE); clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); - clientSecret = new Secret(config.getString(Keys.OPENID_CLIENTSECRET)); - - this.loginService = loginService; + clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET))); try { callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); @@ -85,7 +87,8 @@ public class OpenIdProvider { tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - } catch (URISyntaxException e) { + } catch(URISyntaxException error) { + LOGGER.error("Invalid URIs provided in OpenID configuration"); } adminGroup = config.getString(Keys.OPENID_ADMINGROUP); @@ -105,30 +108,21 @@ public class OpenIdProvider { return request.toURI(); } - private OIDCTokenResponse getToken(AuthorizationCode code) { - // Credentials to authenticate us to the token endpoint - ClientAuthentication clientAuth = new ClientSecretBasic(clientId, clientSecret); + private OIDCTokenResponse getToken(AuthorizationCode code) throws IOException, ParseException, GeneralSecurityException { AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); + TokenRequest tokenRequest = new TokenRequest(tokenUrl, clientAuth, codeGrant); - TokenRequest request = new TokenRequest(tokenUrl, clientAuth, codeGrant); - TokenResponse tokenResponse; - - try { - HTTPResponse tokenReq = request.toHTTPRequest().send(); - tokenResponse = OIDCTokenResponseParser.parse(tokenReq); - if (!tokenResponse.indicatesSuccess()) { - return null; - } - - return (OIDCTokenResponse) tokenResponse.toSuccessResponse(); - } catch (IOException e) { - return null; - } catch (ParseException e) { - return null; + HTTPResponse tokenReq = tokenRequest.toHTTPRequest().send(); + TokenResponse tokenResponse = OIDCTokenResponseParser.parse(tokenReq); + if (!tokenResponse.indicatesSuccess()) { + LOGGER.warn("Invalid authorization code provided to OpenID callback"); + throw new GeneralSecurityException("Unable to authenticate with the OpenID Connect provider."); } + + return (OIDCTokenResponse) tokenResponse.toSuccessResponse(); } - private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException { + private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException, GeneralSecurityException { UserInfoResponse userInfoResponse; HTTPResponse httpResponse = new UserInfoRequest(userInfoUrl, token) @@ -138,46 +132,39 @@ public class OpenIdProvider { userInfoResponse = UserInfoResponse.parse(httpResponse); if (!userInfoResponse.indicatesSuccess()) { - // User info request failed - usually from expiring - return null; + LOGGER.error("Failed to access OpenID user info endpoint"); + throw new GeneralSecurityException("Failed to access OpenID Connect user info endpoint. Please contact your administrator."); } return userInfoResponse.toSuccessResponse().getUserInfo(); } - public Response handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, WebApplicationException { + public URI handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, GeneralSecurityException { AuthorizationResponse response = AuthorizationResponse.parse(requestUri); if (!response.indicatesSuccess()) { - AuthorizationErrorResponse error = response.toErrorResponse(); - throw new WebApplicationException(Response.status(403).entity(error.getErrorObject().getDescription()).build()); + LOGGER.warn("Callback received error response from OpenID identity provider"); + throw new GeneralSecurityException(response.toErrorResponse().getErrorObject().getDescription()); } AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); if (authCode == null) { - return Response.status(403).entity( "Invalid OpenID Connect callback.").build(); + LOGGER.warn("Malformed OpenID callback"); + throw new GeneralSecurityException( "Malformed OpenID callback."); } OIDCTokenResponse tokens = getToken(authCode); - if (tokens == null) { - return Response.status(403).entity("Unable to authenticate with the OpenID Connect provider. Please try again.").build(); - } - BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); UserInfo userInfo = getUserInfo(bearerToken); - if (userInfo == null) { - return Response.status(500).entity("Failed to access OpenID Connect user info endpoint. Please contact your administrator.").build(); - } - User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), userInfo.getStringListClaim("groups").contains(adminGroup)); request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return Response.seeOther( - baseUrl).build(); + + return baseUrl; } } diff --git a/traccar-web b/traccar-web index 091d10531..506dd66b7 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 091d10531a59216c5f0a812609742e097c68ff2c +Subproject commit 506dd66b793803a24a2872e242482f263087df52 -- cgit v1.2.3 From 1019243f07cdd026b573af593323830e9ebd0333 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 17:17:48 +0100 Subject: Further review changes --- .../org/traccar/api/resource/SessionResource.java | 374 +- .../java/org/traccar/database/OpenIdProvider.java | 333 +- swagger.json | 7068 ++++++++++---------- 3 files changed, 3877 insertions(+), 3898 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index a20e5f100..8240a8a6f 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -1,186 +1,188 @@ -/* - * 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. - * 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.api.resource; - -import org.traccar.api.BaseResource; -import org.traccar.api.security.LoginService; -import org.traccar.api.signature.TokenManager; -import org.traccar.database.OpenIdProvider; -import org.traccar.helper.DataConverter; -import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; -import org.traccar.model.User; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import com.nimbusds.oauth2.sdk.ParseException; -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.util.Date; -import java.net.URI; - -@Path("session") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_FORM_URLENCODED) -public class SessionResource extends BaseResource { - - public static final String USER_ID_KEY = "userId"; - public static final String USER_COOKIE_KEY = "user"; - public static final String PASS_COOKIE_KEY = "password"; - - @Inject - private LoginService loginService; - - @Inject - private OpenIdProvider openIdProvider; - - @Inject - private TokenManager tokenManager; - - @Context - private HttpServletRequest request; - - @PermitAll - @GET - public User get(@QueryParam("token") String token) throws StorageException, IOException, GeneralSecurityException { - - if (token != null) { - User user = loginService.login(token); - if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } - } - - Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY); - if (userId == null) { - - Cookie[] cookies = request.getCookies(); - String email = null, password = null; - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookie.getName().equals(USER_COOKIE_KEY)) { - byte[] emailBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); - email = new String(emailBytes, StandardCharsets.UTF_8); - } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { - byte[] passwordBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); - password = new String(passwordBytes, StandardCharsets.UTF_8); - } - } - } - if (email != null && password != null) { - User user = loginService.login(email, password); - if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } - } - - } else { - - User user = permissionsService.getUser(userId); - if (user != null) { - return user; - } - - } - - throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); - } - - @Path("{id}") - @GET - public User get(@PathParam("id") long userId) throws StorageException { - permissionsService.checkUser(getUserId(), userId); - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", userId))); - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } - - @PermitAll - @POST - public User add( - @FormParam("email") String email, @FormParam("password") String password) throws StorageException { - User user = loginService.login(email, password); - if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } else { - LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); - throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); - } - } - - @DELETE - public Response remove() { - LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); - request.getSession().removeAttribute(USER_ID_KEY); - return Response.noContent().build(); - } - - @Path("token") - @POST - public String requestToken( - @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { - return tokenManager.generateToken(getUserId(), expiration); - } - - @PermitAll - @Path("openid/auth") - @GET - public Response openIdAuth() throws IOException { - return Response.seeOther(openIdProvider.createAuthUri()).build(); - } - - @PermitAll - @Path("openid/callback") - @GET - public Response requestToken() throws IOException, StorageException, ParseException, GeneralSecurityException { - StringBuilder requestUrl = new StringBuilder(request.getRequestURL().toString()); - String queryString = request.getQueryString(); - String requestUri = requestUrl.append('?').append(queryString).toString(); - - return Response.seeOther(openIdProvider.handleCallback(URI.create(requestUri), request)).build(); - } -} +/* + * 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. + * 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.api.resource; + +import org.traccar.api.BaseResource; +import org.traccar.api.security.LoginService; +import org.traccar.api.signature.TokenManager; +import org.traccar.database.OpenIdProvider; +import org.traccar.helper.DataConverter; +import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import com.nimbusds.oauth2.sdk.ParseException; +import javax.annotation.Nullable; +import javax.annotation.security.PermitAll; +import javax.inject.Inject; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.util.Date; +import java.net.URI; + +@Path("session") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_FORM_URLENCODED) +public class SessionResource extends BaseResource { + + public static final String USER_ID_KEY = "userId"; + public static final String USER_COOKIE_KEY = "user"; + public static final String PASS_COOKIE_KEY = "password"; + + @Inject + private LoginService loginService; + + @Inject + @Nullable + private OpenIdProvider openIdProvider; + + @Inject + private TokenManager tokenManager; + + @Context + private HttpServletRequest request; + + @PermitAll + @GET + public User get(@QueryParam("token") String token) throws StorageException, IOException, GeneralSecurityException { + + if (token != null) { + User user = loginService.login(token); + if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + } + + Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY); + if (userId == null) { + + Cookie[] cookies = request.getCookies(); + String email = null, password = null; + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equals(USER_COOKIE_KEY)) { + byte[] emailBytes = DataConverter.parseBase64( + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); + email = new String(emailBytes, StandardCharsets.UTF_8); + } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { + byte[] passwordBytes = DataConverter.parseBase64( + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); + password = new String(passwordBytes, StandardCharsets.UTF_8); + } + } + } + if (email != null && password != null) { + User user = loginService.login(email, password); + if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + } + + } else { + + User user = permissionsService.getUser(userId); + if (user != null) { + return user; + } + + } + + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); + } + + @Path("{id}") + @GET + public User get(@PathParam("id") long userId) throws StorageException { + permissionsService.checkUser(getUserId(), userId); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", userId))); + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + + @PermitAll + @POST + public User add( + @FormParam("email") String email, @FormParam("password") String password) throws StorageException { + User user = loginService.login(email, password); + if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } else { + LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); + throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); + } + } + + @DELETE + public Response remove() { + LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); + request.getSession().removeAttribute(USER_ID_KEY); + return Response.noContent().build(); + } + + @Path("token") + @POST + public String requestToken( + @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { + return tokenManager.generateToken(getUserId(), expiration); + } + + @PermitAll + @Path("openid/auth") + @GET + public Response openIdAuth() throws IOException { + return Response.seeOther(openIdProvider.createAuthUri()).build(); + } + + @PermitAll + @Path("openid/callback") + @GET + public Response requestToken() throws IOException, StorageException, ParseException, GeneralSecurityException { + StringBuilder requestUrl = new StringBuilder(request.getRequestURL().toString()); + String queryString = request.getQueryString(); + String requestUri = requestUrl.append('?').append(queryString).toString(); + + return Response.seeOther(openIdProvider.handleCallback(URI.create(requestUri), request)).build(); + } +} diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 6f44d0e80..22e5d6b50 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -1,170 +1,163 @@ -/* - * Copyright 2023 Daniel Raper (me@danr.uk) - * - * 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.database; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.api.resource.SessionResource; -import org.traccar.api.security.LoginService; -import org.traccar.model.User; -import org.traccar.storage.StorageException; -import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; - -import java.net.URI; -import java.net.URISyntaxException; -import java.security.GeneralSecurityException; -import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import com.google.inject.Inject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nimbusds.oauth2.sdk.http.HTTPResponse; -import com.nimbusds.oauth2.sdk.AuthorizationCode; -import com.nimbusds.oauth2.sdk.ResponseType; -import com.nimbusds.oauth2.sdk.Scope; -import com.nimbusds.oauth2.sdk.AuthorizationGrant; -import com.nimbusds.oauth2.sdk.TokenRequest; -import com.nimbusds.oauth2.sdk.TokenResponse; -import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; -import com.nimbusds.oauth2.sdk.ParseException; -import com.nimbusds.oauth2.sdk.AuthorizationResponse; -import com.nimbusds.oauth2.sdk.auth.Secret; -import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; -import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; -import com.nimbusds.oauth2.sdk.token.BearerAccessToken; -import com.nimbusds.oauth2.sdk.id.State; -import com.nimbusds.oauth2.sdk.id.ClientID; -import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; -import com.nimbusds.openid.connect.sdk.Nonce; -import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; -import com.nimbusds.openid.connect.sdk.UserInfoResponse; -import com.nimbusds.openid.connect.sdk.UserInfoRequest; -import com.nimbusds.openid.connect.sdk.AuthenticationRequest; - -import com.nimbusds.openid.connect.sdk.claims.UserInfo; - -public class OpenIdProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); - - public final Boolean force; - private final ClientID clientId; - private final ClientAuthentication clientAuth; - private URI callbackUrl; - private URI authUrl; - private URI tokenUrl; - private URI userInfoUrl; - private URI baseUrl; - private final String adminGroup; - - private LoginService loginService; - - @Inject - public OpenIdProvider(Config config, LoginService loginService) { - this.loginService = loginService; - - force = config.getBoolean(Keys.OPENID_FORCE); - clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); - clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET))); - - try { - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, "")); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - } catch(URISyntaxException error) { - LOGGER.error("Invalid URIs provided in OpenID configuration"); - } - - adminGroup = config.getString(Keys.OPENID_ADMINGROUP); - } - - public URI createAuthUri() { - AuthenticationRequest request = new AuthenticationRequest.Builder( - new ResponseType("code"), - new Scope("openid", "profile", "email", "groups"), - clientId, - callbackUrl) - .endpointURI(authUrl) - .state(new State()) - .nonce(new Nonce()) - .build(); - - return request.toURI(); - } - - private OIDCTokenResponse getToken(AuthorizationCode code) throws IOException, ParseException, GeneralSecurityException { - AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); - TokenRequest tokenRequest = new TokenRequest(tokenUrl, clientAuth, codeGrant); - - HTTPResponse tokenReq = tokenRequest.toHTTPRequest().send(); - TokenResponse tokenResponse = OIDCTokenResponseParser.parse(tokenReq); - if (!tokenResponse.indicatesSuccess()) { - LOGGER.warn("Invalid authorization code provided to OpenID callback"); - throw new GeneralSecurityException("Unable to authenticate with the OpenID Connect provider."); - } - - return (OIDCTokenResponse) tokenResponse.toSuccessResponse(); - } - - private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException, GeneralSecurityException { - UserInfoResponse userInfoResponse; - - HTTPResponse httpResponse = new UserInfoRequest(userInfoUrl, token) - .toHTTPRequest() - .send(); - - userInfoResponse = UserInfoResponse.parse(httpResponse); - - if (!userInfoResponse.indicatesSuccess()) { - LOGGER.error("Failed to access OpenID user info endpoint"); - throw new GeneralSecurityException("Failed to access OpenID Connect user info endpoint. Please contact your administrator."); - } - - return userInfoResponse.toSuccessResponse().getUserInfo(); - } - - public URI handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, GeneralSecurityException { - AuthorizationResponse response = AuthorizationResponse.parse(requestUri); - - if (!response.indicatesSuccess()) { - LOGGER.warn("Callback received error response from OpenID identity provider"); - throw new GeneralSecurityException(response.toErrorResponse().getErrorObject().getDescription()); - } - - AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); - - if (authCode == null) { - LOGGER.warn("Malformed OpenID callback"); - throw new GeneralSecurityException( "Malformed OpenID callback."); - } - - OIDCTokenResponse tokens = getToken(authCode); - - BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); - - UserInfo userInfo = getUserInfo(bearerToken); - - User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), userInfo.getStringListClaim("groups").contains(adminGroup)); - - request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - - return baseUrl; - } -} +/* + * Copyright 2023 Daniel Raper (me@danr.uk) + * + * 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.database; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.api.resource.SessionResource; +import org.traccar.api.security.LoginService; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; + +import java.net.URI; +import java.net.URISyntaxException; +import java.security.GeneralSecurityException; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import com.google.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nimbusds.oauth2.sdk.http.HTTPResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCode; +import com.nimbusds.oauth2.sdk.ResponseType; +import com.nimbusds.oauth2.sdk.Scope; +import com.nimbusds.oauth2.sdk.AuthorizationGrant; +import com.nimbusds.oauth2.sdk.TokenRequest; +import com.nimbusds.oauth2.sdk.TokenResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; +import com.nimbusds.oauth2.sdk.ParseException; +import com.nimbusds.oauth2.sdk.AuthorizationResponse; +import com.nimbusds.oauth2.sdk.auth.Secret; +import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; +import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; +import com.nimbusds.oauth2.sdk.token.BearerAccessToken; +import com.nimbusds.oauth2.sdk.id.State; +import com.nimbusds.oauth2.sdk.id.ClientID; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; +import com.nimbusds.openid.connect.sdk.Nonce; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; +import com.nimbusds.openid.connect.sdk.UserInfoResponse; +import com.nimbusds.openid.connect.sdk.UserInfoRequest; +import com.nimbusds.openid.connect.sdk.AuthenticationRequest; + +import com.nimbusds.openid.connect.sdk.claims.UserInfo; + +public class OpenIdProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); + + public final Boolean force; + private final ClientID clientId; + private final ClientAuthentication clientAuth; + private URI callbackUrl; + private URI authUrl; + private URI tokenUrl; + private URI userInfoUrl; + private URI baseUrl; + private final String adminGroup; + + private LoginService loginService; + + @Inject + public OpenIdProvider(Config config, LoginService loginService) { + this.loginService = loginService; + + force = config.getBoolean(Keys.OPENID_FORCE); + clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); + clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET))); + + try { + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, "")); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + } catch(URISyntaxException error) { + LOGGER.error("Invalid URIs provided in OpenID configuration"); + } + + adminGroup = config.getString(Keys.OPENID_ADMINGROUP); + } + + public URI createAuthUri() { + AuthenticationRequest.Builder request = new AuthenticationRequest.Builder( + new ResponseType("code"), + new Scope("openid", "profile", "email", "groups"), + clientId, + callbackUrl); + + return request.endpointURI(authUrl) + .state(new State()) + .build() + .toURI(); + } + + private OIDCTokenResponse getToken(AuthorizationCode code) throws IOException, ParseException, GeneralSecurityException { + AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); + TokenRequest tokenRequest = new TokenRequest(tokenUrl, clientAuth, codeGrant); + + HTTPResponse tokenResponse = tokenRequest.toHTTPRequest().send(); + TokenResponse token = OIDCTokenResponseParser.parse(tokenResponse); + if (!token.indicatesSuccess()) { + throw new GeneralSecurityException("Unable to authenticate with the OpenID Connect provider."); + } + + return (OIDCTokenResponse) token.toSuccessResponse(); + } + + private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException, GeneralSecurityException { + HTTPResponse httpResponse = new UserInfoRequest(userInfoUrl, token) + .toHTTPRequest() + .send(); + + UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse); + + if (!userInfoResponse.indicatesSuccess()) { + throw new GeneralSecurityException("Failed to access OpenID Connect user info endpoint. Please contact your administrator."); + } + + return userInfoResponse.toSuccessResponse().getUserInfo(); + } + + public URI handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, GeneralSecurityException { + AuthorizationResponse response = AuthorizationResponse.parse(requestUri); + + if (!response.indicatesSuccess()) { + throw new GeneralSecurityException(response.toErrorResponse().getErrorObject().getDescription()); + } + + AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); + + if (authCode == null) { + throw new GeneralSecurityException( "Malformed OpenID callback."); + } + + OIDCTokenResponse tokens = getToken(authCode); + + BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); + + UserInfo userInfo = getUserInfo(bearerToken); + + User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), userInfo.getStringListClaim("groups").contains(adminGroup)); + + request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + + return baseUrl; + } +} diff --git a/swagger.json b/swagger.json index d3a83ba76..5a7349da8 100644 --- a/swagger.json +++ b/swagger.json @@ -1,3542 +1,3526 @@ -{ - "openapi": "3.0.1", - "info": { - "title": "Traccar", - "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", - "url": "https://www.traccar.org/", - "email": "support@traccar.org" - }, - "license": { - "name": "Apache 2.0", - "url": "https://www.apache.org/licenses/LICENSE-2.0.html" - } - }, - "servers": [ - { - "url": "https://demo.traccar.org/api", - "description": "Demo Server 1" - }, - { - "url": "https://demo2.traccar.org/api", - "description": "Demo Server 2" - }, - { - "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" - }, - { - "url": "http://{host}:{port}/api", - "description": "Other Server", - "variables": { - "host": { - "default": "localhost" - }, - "port": { - "enum": [ - "8082", - "80" - ], - "default": "8082" - } - } - } - ], - "security": [ - { - "basicAuth": [] - } - ], - "tags": [ - { - "name": "Server", - "description": "Server information" - }, - { - "name": "Session", - "description": "User session management" - }, - { - "name": "Devices", - "description": "Device management" - }, - { - "name": "Groups", - "description": "Group management" - }, - { - "name": "Users", - "description": "User management" - }, - { - "name": "Permissions", - "description": "User permissions and other object linking" - }, - { - "name": "Positions", - "description": "Retrieving raw location information" - }, - { - "name": "Events", - "description": "Retrieving event information" - }, - { - "name": "Reports", - "description": "Reports generation" - }, - { - "name": "Notifications", - "description": "User notifications management" - }, - { - "name": "Geofences", - "description": "Geofence management" - }, - { - "name": "Commands", - "description": "Sending commands to devices and stored command management" - }, - { - "name": "Attributes", - "description": "Computed attributes management" - }, - { - "name": "Drivers", - "description": "Drivers management" - }, - { - "name": "Maintenance", - "description": "Maintenance management" - }, - { - "name": "Calendars", - "description": "Calendar management" - }, - { - "name": "Statistics", - "description": "Retrieving server statistics" - } - ], - "paths": { - "/commands": { - "get": { - "summary": "Fetch a list of Saved Commands", - "tags": [ - "Commands" - ], - "description": "Without params, it returns a list of Saved Commands the user has access to", - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Command" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Saved Command", - "tags": [ - "Commands" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/commands/{id}": { - "put": { - "summary": "Update a Saved Command", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Saved Command", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/commands/send": { - "get": { - "summary": "Fetch a list of Saved Commands supported by Device at the moment", - "description": "Return a list of saved commands linked to Device and its groups, filtered by current Device protocol support", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Command" - } - } - } - } - }, - "400": { - "description": "Could happen when the user doesn't have permission for the device", - "content": {} - } - } - }, - "post": { - "summary": "Dispatch commands to device", - "description": "Dispatch a new command or Saved Command if _body.id_ set", - "tags": [ - "Commands" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Command sent", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - }, - "202": { - "description": "Command queued", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - }, - "400": { - "description": "Could happen when the user doesn't have permission or an incorrect command _type_ for the device", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/commands/types": { - "get": { - "summary": "Fetch a list of available Commands for the Device or all possible Commands if Device ommited", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "description": "Internal device identifier. Only works if device has already reported some locations", - "schema": { - "type": "integer" - } - }, - { - "name": "protocol", - "in": "query", - "description": "Protocol name. Can be used instead of device id", - "schema": { - "type": "string" - } - }, - { - "name": "textChannel", - "in": "query", - "description": "When `true` return SMS commands. If not specified or `false` return data commands", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CommandType" - } - } - } - } - }, - "400": { - "description": "Could happen when trying to fetch from a device the user does not have permission", - "content": {} - } - } - } - }, - "/devices": { - "get": { - "summary": "Fetch a list of Devices", - "description": "Without any params, returns a list of the user's devices", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "id", - "in": "query", - "description": "To fetch one or more devices. Multiple params can be passed like `id=31&id=42`", - "schema": { - "type": "integer" - } - }, - { - "name": "uniqueId", - "in": "query", - "description": "To fetch one or more devices. Multiple params can be passed like `uniqueId=333331&uniqieId=44442`", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Device" - } - } - } - } - }, - "400": { - "description": "No permission", - "content": {} - } - } - }, - "post": { - "summary": "Create a Device", - "tags": [ - "Devices" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/devices/{id}": { - "put": { - "summary": "Update a Device", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Device", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/devices/{id}/accumulators": { - "put": { - "summary": "Update total distance and hours of the Device", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeviceAccumulators" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/groups": { - "get": { - "summary": "Fetch a list of Groups", - "description": "Without any params, returns a list of the Groups the user belongs to", - "tags": [ - "Groups" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Group" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Group", - "tags": [ - "Groups" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - } - }, - "400": { - "description": "No permission", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/groups/{id}": { - "put": { - "summary": "Update a Group", - "tags": [ - "Groups" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Group", - "tags": [ - "Groups" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/permissions": { - "post": { - "summary": "Link an Object to another Object", - "tags": [ - "Permissions" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Permission" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content", - "content": {} - }, - "400": { - "description": "No permission", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Unlink an Object from another Object", - "tags": [ - "Permissions" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Permission" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/positions": { - "get": { - "summary": "Fetches a list of Positions", - "description": "We strongly recommend using [Traccar WebSocket API](https://www.traccar.org/traccar-api/) instead of periodically polling positions endpoint. Without any params, it returns a list of last known positions for all the user's Devices. _from_ and _to_ fields are not required with _id_.", - "tags": [ - "Positions" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "description": "_deviceId_ is optional, but requires the _from_ and _to_ parameters when used", - "schema": { - "type": "integer" - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "id", - "in": "query", - "description": "To fetch one or more positions. Multiple params can be passed like `id=31&id=42`", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - }, - "text/csv": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - }, - "application/gpx+xml": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - } - } - } - } - } - }, - "/server": { - "get": { - "summary": "Fetch Server information", - "tags": [ - "Server" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Server" - } - } - } - } - } - }, - "put": { - "summary": "Update Server information", - "tags": [ - "Server" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Server" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Server" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/session": { - "get": { - "summary": "Fetch Session information", - "tags": [ - "Session" - ], - "parameters": [ - { - "name": "token", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "404": { - "description": "Not Found", - "content": {} - } - } - }, - "post": { - "summary": "Create a new Session", - "tags": [ - "Session" - ], - "requestBody": { - "content": { - "application/x-www-form-urlencoded": { - "schema": { - "required": [ - "email", - "password" - ], - "properties": { - "email": { - "type": "string" - }, - "password": { - "type": "string", - "format": "password" - } - } - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": {} - } - } - }, - "delete": { - "summary": "Close the Session", - "tags": [ - "Session" - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/session/openid/auth": { - "get": { - "summary": "Fetch Session information", - "tags": [ - "Session" - ], - "parameters": [ - { - } - ], - "responses": { - "303": { - "description": "Redirect to OpenID Connect identity provider", - "content": { } - }, - "404": { - "description": "OpenID Connect disabled", - "content": { } - } - } - } - }, - "/session/openid/callback": { - "get": { - "summary": "OpenID Callback", - "tags": [ - "Session" - ], - "parameters": [ - { - } - ], - "responses": { - "303": { - "description": "Successful authentication, redirect to homepage", - "content": { } - }, - "403": { - "description": "Invalid callback or negative response from identity provider", - "content": { } - }, - "404": { - "description": "OpenID Connect disabled", - "content": { } - }, - "500": { - "description": "Other OpenID Connect error", - "content": { } - } - } - } - }, - "/users": { - "get": { - "summary": "Fetch a list of Users", - "tags": [ - "Users" - ], - "parameters": [ - { - "name": "userId", - "in": "query", - "description": "Can only be used by admin or manager users", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "400": { - "description": "No Permission", - "content": {} - } - } - }, - "post": { - "summary": "Create a User", - "tags": [ - "Users" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/users/{id}": { - "put": { - "summary": "Update a User", - "tags": [ - "Users" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a User", - "tags": [ - "Users" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/notifications": { - "get": { - "summary": "Fetch a list of Notifications", - "description": "Without params, it returns a list of Notifications the user has access to", - "tags": [ - "Notifications" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Notification" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Notification", - "tags": [ - "Notifications" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/notifications/{id}": { - "put": { - "summary": "Update a Notification", - "tags": [ - "Notifications" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Notification", - "tags": [ - "Notifications" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/notifications/types": { - "get": { - "summary": "Fetch a list of available Notification types", - "tags": [ - "Notifications" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationType" - } - } - } - } - } - } - } - }, - "/notifications/test": { - "post": { - "summary": "Send test notification to current user via Email and SMS", - "tags": [ - "Notifications" - ], - "responses": { - "204": { - "description": "Successful sending", - "content": {} - }, - "400": { - "description": "Could happen if sending has failed", - "content": {} - } - } - } - }, - "/geofences": { - "get": { - "summary": "Fetch a list of Geofences", - "description": "Without params, it returns a list of Geofences the user has access to", - "tags": [ - "Geofences" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Geofence" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Geofence", - "tags": [ - "Geofences" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/geofences/{id}": { - "put": { - "summary": "Update a Geofence", - "tags": [ - "Geofences" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Geofence", - "tags": [ - "Geofences" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/events/{id}": { - "get": { - "tags": [ - "Events" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Event" - } - } - } - } - } - } - }, - "/reports/route": { - "get": { - "summary": "Fetch a list of Positions within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - } - } - } - } - } - }, - "/reports/events": { - "get": { - "summary": "Fetch a list of Events within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "type", - "in": "query", - "description": "% can be used to return events of all types", - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Event" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Event" - } - } - } - } - } - } - } - }, - "/reports/summary": { - "get": { - "summary": "Fetch a list of ReportSummary within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportSummary" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportSummary" - } - } - } - } - } - } - } - }, - "/reports/trips": { - "get": { - "summary": "Fetch a list of ReportTrips within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportTrips" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportTrips" - } - } - } - } - } - } - } - }, - "/reports/stops": { - "get": { - "summary": "Fetch a list of ReportStops within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportStops" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportStops" - } - } - } - } - } - } - } - }, - "/statistics": { - "get": { - "summary": "Fetch server Statistics", - "tags": [ - "Statistics" - ], - "parameters": [ - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Statistics" - } - } - } - } - } - } - } - }, - "/calendars": { - "get": { - "summary": "Fetch a list of Calendars", - "description": "Without params, it returns a list of Calendars the user has access to", - "tags": [ - "Calendars" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Calendar" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Calendar", - "tags": [ - "Calendars" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/calendars/{id}": { - "put": { - "summary": "Update a Calendar", - "tags": [ - "Calendars" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Calendar", - "tags": [ - "Calendars" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/attributes/computed": { - "get": { - "summary": "Fetch a list of Attributes", - "description": "Without params, it returns a list of Attributes the user has access to", - "tags": [ - "Attributes" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Attribute" - } - } - } - } - } - } - }, - "post": { - "summary": "Create an Attribute", - "tags": [ - "Attributes" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/attributes/computed/{id}": { - "put": { - "summary": "Update an Attribute", - "tags": [ - "Attributes" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete an Attribute", - "tags": [ - "Attributes" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/drivers": { - "get": { - "summary": "Fetch a list of Drivers", - "description": "Without params, it returns a list of Drivers the user has access to", - "tags": [ - "Drivers" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Driver" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Driver", - "tags": [ - "Drivers" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/drivers/{id}": { - "put": { - "summary": "Update a Driver", - "tags": [ - "Drivers" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Driver", - "tags": [ - "Drivers" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/maintenance": { - "get": { - "summary": "Fetch a list of Maintenance", - "description": "Without params, it returns a list of Maintenance the user has access to", - "tags": [ - "Maintenance" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Maintenance" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Maintenance", - "tags": [ - "Maintenance" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/maintenance/{id}": { - "put": { - "summary": "Update a Maintenance", - "tags": [ - "Maintenance" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Maintenance", - "tags": [ - "Maintenance" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - } - }, - "components": { - "schemas": { - "Position": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "deviceId": { - "type": "integer" - }, - "protocol": { - "type": "string" - }, - "deviceTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "fixTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "serverTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "outdated": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - }, - "latitude": { - "type": "number" - }, - "longitude": { - "type": "number" - }, - "altitude": { - "type": "number" - }, - "speed": { - "type": "number", - "description": "in knots" - }, - "course": { - "type": "number" - }, - "address": { - "type": "string" - }, - "accuracy": { - "type": "number" - }, - "network": { - "type": "object", - "properties": {} - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "User": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "email": { - "type": "string" - }, - "phone": { - "type": "string" - }, - "readonly": { - "type": "boolean" - }, - "administrator": { - "type": "boolean" - }, - "map": { - "type": "string" - }, - "latitude": { - "type": "number" - }, - "longitude": { - "type": "number" - }, - "zoom": { - "type": "integer" - }, - "password": { - "type": "string" - }, - "twelveHourFormat": { - "type": "boolean" - }, - "coordinateFormat": { - "type": "string" - }, - "disabled": { - "type": "boolean" - }, - "expirationTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "deviceLimit": { - "type": "integer" - }, - "userLimit": { - "type": "integer" - }, - "deviceReadonly": { - "type": "boolean" - }, - "limitCommands": { - "type": "boolean" - }, - "poiLayer": { - "type": "string" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Server": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "registration": { - "type": "boolean" - }, - "readonly": { - "type": "boolean" - }, - "deviceReadonly": { - "type": "boolean" - }, - "limitCommands": { - "type": "boolean" - }, - "map": { - "type": "string" - }, - "bingKey": { - "type": "string" - }, - "mapUrl": { - "type": "string" - }, - "poiLayer": { - "type": "string" - }, - "latitude": { - "type": "number" - }, - "longitude": { - "type": "number" - }, - "zoom": { - "type": "integer" - }, - "twelveHourFormat": { - "type": "boolean" - }, - "version": { - "type": "string" - }, - "forceSettings": { - "type": "boolean" - }, - "coordinateFormat": { - "type": "string" - }, - "oidcEnabled": { - "type": "boolean" - }, - "oidcForce": { - "type": "boolean" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Command": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "deviceId": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Device": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "uniqueId": { - "type": "string" - }, - "status": { - "type": "string" - }, - "disabled": { - "type": "boolean" - }, - "lastUpdate": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "positionId": { - "type": "integer" - }, - "groupId": { - "type": "integer" - }, - "phone": { - "type": "string" - }, - "model": { - "type": "string" - }, - "contact": { - "type": "string" - }, - "category": { - "type": "string" - }, - "geofenceIds": { - "type": "array", - "items": { - "type": "integer" - } - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Group": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "groupId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Permission": { - "type": "object", - "properties": { - "userId": { - "type": "integer", - "description": "User Id, can be only first parameter" - }, - "deviceId": { - "type": "integer", - "description": "Device Id, can be first parameter or second only in combination with userId" - }, - "groupId": { - "type": "integer", - "description": "Group Id, can be first parameter or second only in combination with userId" - }, - "geofenceId": { - "type": "integer", - "description": "Geofence Id, can be second parameter only" - }, - "notificationId": { - "type": "integer", - "description": "Notification Id, can be second parameter only" - }, - "calendarId": { - "type": "integer", - "description": "Calendar Id, can be second parameter only and only in combination with userId" - }, - "attributeId": { - "type": "integer", - "description": "Computed Attribute Id, can be second parameter only" - }, - "driverId": { - "type": "integer", - "description": "Driver Id, can be second parameter only" - }, - "managedUserId": { - "type": "integer", - "description": "User Id, can be second parameter only and only in combination with userId" - } - }, - "description": "This is a permission map that contain two object indexes. It is used to link/unlink objects. Order is important. Example: { deviceId:8, geofenceId: 16 }" - }, - "CommandType": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - } - }, - "Geofence": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "area": { - "type": "string" - }, - "calendarId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Notification": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "type": "string" - }, - "always": { - "type": "boolean" - }, - "web": { - "type": "boolean" - }, - "mail": { - "type": "boolean" - }, - "sms": { - "type": "boolean" - }, - "calendarId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "NotificationType": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - } - }, - "Event": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "type": "string" - }, - "eventTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "deviceId": { - "type": "integer" - }, - "positionId": { - "type": "integer" - }, - "geofenceId": { - "type": "integer" - }, - "maintenanceId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "ReportSummary": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "deviceName": { - "type": "string" - }, - "maxSpeed": { - "type": "number", - "description": "in knots" - }, - "averageSpeed": { - "type": "number", - "description": "in knots" - }, - "distance": { - "type": "number", - "description": "in meters" - }, - "spentFuel": { - "type": "number", - "description": "in liters" - }, - "engineHours": { - "type": "integer" - } - } - }, - "ReportTrips": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "deviceName": { - "type": "string" - }, - "maxSpeed": { - "type": "number", - "description": "in knots" - }, - "averageSpeed": { - "type": "number", - "description": "in knots" - }, - "distance": { - "type": "number", - "description": "in meters" - }, - "spentFuel": { - "type": "number", - "description": "in liters" - }, - "duration": { - "type": "integer" - }, - "startTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "startAddress": { - "type": "string" - }, - "startLat": { - "type": "number" - }, - "startLon": { - "type": "number" - }, - "endTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "endAddress": { - "type": "string" - }, - "endLat": { - "type": "number" - }, - "endLon": { - "type": "number" - }, - "driverUniqueId": { - "type": "integer" - }, - "driverName": { - "type": "string" - } - } - }, - "ReportStops": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "deviceName": { - "type": "string" - }, - "duration": { - "type": "integer" - }, - "startTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "address": { - "type": "string" - }, - "lat": { - "type": "number" - }, - "lon": { - "type": "number" - }, - "endTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "spentFuel": { - "type": "number", - "description": "in liters" - }, - "engineHours": { - "type": "integer" - } - } - }, - "Statistics": { - "type": "object", - "properties": { - "captureTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "activeUsers": { - "type": "integer" - }, - "activeDevices": { - "type": "integer" - }, - "requests": { - "type": "integer" - }, - "messagesReceived": { - "type": "integer" - }, - "messagesStored": { - "type": "integer" - } - } - }, - "DeviceAccumulators": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "totalDistance": { - "type": "number", - "description": "in meters" - }, - "hours": { - "type": "number" - } - } - }, - "Calendar": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "data": { - "type": "string", - "description": "base64 encoded in iCalendar format" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Attribute": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "attribute": { - "type": "string" - }, - "expression": { - "type": "string" - }, - "type": { - "type": "string", - "description": "String|Number|Boolean" - } - } - }, - "Driver": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "uniqueId": { - "type": "string" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Maintenance": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - }, - "start": { - "type": "number" - }, - "period": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - }, - "parameters": { - "entityId": { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - }, - "all": { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - "refresh": { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - }, - "userId": { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - "deviceId": { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - "groupId": { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - "deviceIdArray": { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - "groupIdArray": { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - "fromTime": { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - "toTime": { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - }, - "requestBodies": { - "Device": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, - "Permission": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Permission" - } - } - }, - "required": true - }, - "Group": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - }, - "required": true - }, - "User": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": true - }, - "Geofence": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - }, - "required": true - }, - "Calendar": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - }, - "required": true - }, - "Attribute": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - }, - "required": true - }, - "Driver": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - }, - "required": true - }, - "Command": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "Notification": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - }, - "required": true - }, - "Maintenance": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - }, - "required": true - } - }, - "securitySchemes": { - "basicAuth": { - "type": "http", - "description": "Basic HTTP authorization with _email_ and _password_", - "scheme": "basic" - } - } - } -} +{ + "openapi": "3.0.1", + "info": { + "title": "Traccar", + "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", + "url": "https://www.traccar.org/", + "email": "support@traccar.org" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "servers": [ + { + "url": "https://demo.traccar.org/api", + "description": "Demo Server 1" + }, + { + "url": "https://demo2.traccar.org/api", + "description": "Demo Server 2" + }, + { + "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" + }, + { + "url": "http://{host}:{port}/api", + "description": "Other Server", + "variables": { + "host": { + "default": "localhost" + }, + "port": { + "enum": [ + "8082", + "80" + ], + "default": "8082" + } + } + } + ], + "security": [ + { + "basicAuth": [] + } + ], + "tags": [ + { + "name": "Server", + "description": "Server information" + }, + { + "name": "Session", + "description": "User session management" + }, + { + "name": "Devices", + "description": "Device management" + }, + { + "name": "Groups", + "description": "Group management" + }, + { + "name": "Users", + "description": "User management" + }, + { + "name": "Permissions", + "description": "User permissions and other object linking" + }, + { + "name": "Positions", + "description": "Retrieving raw location information" + }, + { + "name": "Events", + "description": "Retrieving event information" + }, + { + "name": "Reports", + "description": "Reports generation" + }, + { + "name": "Notifications", + "description": "User notifications management" + }, + { + "name": "Geofences", + "description": "Geofence management" + }, + { + "name": "Commands", + "description": "Sending commands to devices and stored command management" + }, + { + "name": "Attributes", + "description": "Computed attributes management" + }, + { + "name": "Drivers", + "description": "Drivers management" + }, + { + "name": "Maintenance", + "description": "Maintenance management" + }, + { + "name": "Calendars", + "description": "Calendar management" + }, + { + "name": "Statistics", + "description": "Retrieving server statistics" + } + ], + "paths": { + "/commands": { + "get": { + "summary": "Fetch a list of Saved Commands", + "tags": [ + "Commands" + ], + "description": "Without params, it returns a list of Saved Commands the user has access to", + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Saved Command", + "tags": [ + "Commands" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/commands/{id}": { + "put": { + "summary": "Update a Saved Command", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Saved Command", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/commands/send": { + "get": { + "summary": "Fetch a list of Saved Commands supported by Device at the moment", + "description": "Return a list of saved commands linked to Device and its groups, filtered by current Device protocol support", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Command" + } + } + } + } + }, + "400": { + "description": "Could happen when the user doesn't have permission for the device", + "content": {} + } + } + }, + "post": { + "summary": "Dispatch commands to device", + "description": "Dispatch a new command or Saved Command if _body.id_ set", + "tags": [ + "Commands" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Command sent", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "202": { + "description": "Command queued", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "400": { + "description": "Could happen when the user doesn't have permission or an incorrect command _type_ for the device", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/commands/types": { + "get": { + "summary": "Fetch a list of available Commands for the Device or all possible Commands if Device ommited", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "description": "Internal device identifier. Only works if device has already reported some locations", + "schema": { + "type": "integer" + } + }, + { + "name": "protocol", + "in": "query", + "description": "Protocol name. Can be used instead of device id", + "schema": { + "type": "string" + } + }, + { + "name": "textChannel", + "in": "query", + "description": "When `true` return SMS commands. If not specified or `false` return data commands", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommandType" + } + } + } + } + }, + "400": { + "description": "Could happen when trying to fetch from a device the user does not have permission", + "content": {} + } + } + } + }, + "/devices": { + "get": { + "summary": "Fetch a list of Devices", + "description": "Without any params, returns a list of the user's devices", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "id", + "in": "query", + "description": "To fetch one or more devices. Multiple params can be passed like `id=31&id=42`", + "schema": { + "type": "integer" + } + }, + { + "name": "uniqueId", + "in": "query", + "description": "To fetch one or more devices. Multiple params can be passed like `uniqueId=333331&uniqieId=44442`", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Device" + } + } + } + } + }, + "400": { + "description": "No permission", + "content": {} + } + } + }, + "post": { + "summary": "Create a Device", + "tags": [ + "Devices" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/devices/{id}": { + "put": { + "summary": "Update a Device", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Device", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/devices/{id}/accumulators": { + "put": { + "summary": "Update total distance and hours of the Device", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceAccumulators" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/groups": { + "get": { + "summary": "Fetch a list of Groups", + "description": "Without any params, returns a list of the Groups the user belongs to", + "tags": [ + "Groups" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Group" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Group", + "tags": [ + "Groups" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + } + }, + "400": { + "description": "No permission", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/groups/{id}": { + "put": { + "summary": "Update a Group", + "tags": [ + "Groups" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Group", + "tags": [ + "Groups" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/permissions": { + "post": { + "summary": "Link an Object to another Object", + "tags": [ + "Permissions" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Permission" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content", + "content": {} + }, + "400": { + "description": "No permission", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Unlink an Object from another Object", + "tags": [ + "Permissions" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Permission" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/positions": { + "get": { + "summary": "Fetches a list of Positions", + "description": "We strongly recommend using [Traccar WebSocket API](https://www.traccar.org/traccar-api/) instead of periodically polling positions endpoint. Without any params, it returns a list of last known positions for all the user's Devices. _from_ and _to_ fields are not required with _id_.", + "tags": [ + "Positions" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "description": "_deviceId_ is optional, but requires the _from_ and _to_ parameters when used", + "schema": { + "type": "integer" + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "id", + "in": "query", + "description": "To fetch one or more positions. Multiple params can be passed like `id=31&id=42`", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + }, + "text/csv": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + }, + "application/gpx+xml": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + } + } + } + } + } + }, + "/server": { + "get": { + "summary": "Fetch Server information", + "tags": [ + "Server" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Server" + } + } + } + } + } + }, + "put": { + "summary": "Update Server information", + "tags": [ + "Server" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Server" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Server" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/session": { + "get": { + "summary": "Fetch Session information", + "tags": [ + "Session" + ], + "parameters": [ + { + "name": "token", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "404": { + "description": "Not Found", + "content": {} + } + } + }, + "post": { + "summary": "Create a new Session", + "tags": [ + "Session" + ], + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "required": [ + "email", + "password" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string", + "format": "password" + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + } + } + }, + "delete": { + "summary": "Close the Session", + "tags": [ + "Session" + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/session/openid/auth": { + "get": { + "summary": "Fetch Session information", + "tags": [ + "Session" + ], + "parameters": [ + { + } + ], + "responses": { + "303": { + "description": "Redirect to OpenID Connect identity provider", + "content": { } + } + } + } + }, + "/session/openid/callback": { + "get": { + "summary": "OpenID Callback", + "tags": [ + "Session" + ], + "parameters": [ + { + } + ], + "responses": { + "303": { + "description": "Successful authentication, redirect to homepage", + "content": { } + } + } + } + }, + "/users": { + "get": { + "summary": "Fetch a list of Users", + "tags": [ + "Users" + ], + "parameters": [ + { + "name": "userId", + "in": "query", + "description": "Can only be used by admin or manager users", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "400": { + "description": "No Permission", + "content": {} + } + } + }, + "post": { + "summary": "Create a User", + "tags": [ + "Users" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/users/{id}": { + "put": { + "summary": "Update a User", + "tags": [ + "Users" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a User", + "tags": [ + "Users" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/notifications": { + "get": { + "summary": "Fetch a list of Notifications", + "description": "Without params, it returns a list of Notifications the user has access to", + "tags": [ + "Notifications" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Notification", + "tags": [ + "Notifications" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/notifications/{id}": { + "put": { + "summary": "Update a Notification", + "tags": [ + "Notifications" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Notification", + "tags": [ + "Notifications" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/notifications/types": { + "get": { + "summary": "Fetch a list of available Notification types", + "tags": [ + "Notifications" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationType" + } + } + } + } + } + } + } + }, + "/notifications/test": { + "post": { + "summary": "Send test notification to current user via Email and SMS", + "tags": [ + "Notifications" + ], + "responses": { + "204": { + "description": "Successful sending", + "content": {} + }, + "400": { + "description": "Could happen if sending has failed", + "content": {} + } + } + } + }, + "/geofences": { + "get": { + "summary": "Fetch a list of Geofences", + "description": "Without params, it returns a list of Geofences the user has access to", + "tags": [ + "Geofences" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Geofence" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Geofence", + "tags": [ + "Geofences" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/geofences/{id}": { + "put": { + "summary": "Update a Geofence", + "tags": [ + "Geofences" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Geofence", + "tags": [ + "Geofences" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/events/{id}": { + "get": { + "tags": [ + "Events" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + } + } + } + } + } + } + }, + "/reports/route": { + "get": { + "summary": "Fetch a list of Positions within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + } + } + } + } + } + }, + "/reports/events": { + "get": { + "summary": "Fetch a list of Events within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "type", + "in": "query", + "description": "% can be used to return events of all types", + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Event" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Event" + } + } + } + } + } + } + } + }, + "/reports/summary": { + "get": { + "summary": "Fetch a list of ReportSummary within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportSummary" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportSummary" + } + } + } + } + } + } + } + }, + "/reports/trips": { + "get": { + "summary": "Fetch a list of ReportTrips within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportTrips" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportTrips" + } + } + } + } + } + } + } + }, + "/reports/stops": { + "get": { + "summary": "Fetch a list of ReportStops within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportStops" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportStops" + } + } + } + } + } + } + } + }, + "/statistics": { + "get": { + "summary": "Fetch server Statistics", + "tags": [ + "Statistics" + ], + "parameters": [ + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Statistics" + } + } + } + } + } + } + } + }, + "/calendars": { + "get": { + "summary": "Fetch a list of Calendars", + "description": "Without params, it returns a list of Calendars the user has access to", + "tags": [ + "Calendars" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Calendar" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Calendar", + "tags": [ + "Calendars" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/calendars/{id}": { + "put": { + "summary": "Update a Calendar", + "tags": [ + "Calendars" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Calendar", + "tags": [ + "Calendars" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/attributes/computed": { + "get": { + "summary": "Fetch a list of Attributes", + "description": "Without params, it returns a list of Attributes the user has access to", + "tags": [ + "Attributes" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Attribute" + } + } + } + } + } + } + }, + "post": { + "summary": "Create an Attribute", + "tags": [ + "Attributes" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/attributes/computed/{id}": { + "put": { + "summary": "Update an Attribute", + "tags": [ + "Attributes" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete an Attribute", + "tags": [ + "Attributes" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/drivers": { + "get": { + "summary": "Fetch a list of Drivers", + "description": "Without params, it returns a list of Drivers the user has access to", + "tags": [ + "Drivers" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Driver" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Driver", + "tags": [ + "Drivers" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/drivers/{id}": { + "put": { + "summary": "Update a Driver", + "tags": [ + "Drivers" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Driver", + "tags": [ + "Drivers" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/maintenance": { + "get": { + "summary": "Fetch a list of Maintenance", + "description": "Without params, it returns a list of Maintenance the user has access to", + "tags": [ + "Maintenance" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Maintenance" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Maintenance", + "tags": [ + "Maintenance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/maintenance/{id}": { + "put": { + "summary": "Update a Maintenance", + "tags": [ + "Maintenance" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Maintenance", + "tags": [ + "Maintenance" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + } + }, + "components": { + "schemas": { + "Position": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "deviceId": { + "type": "integer" + }, + "protocol": { + "type": "string" + }, + "deviceTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "fixTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "serverTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "outdated": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + }, + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + }, + "altitude": { + "type": "number" + }, + "speed": { + "type": "number", + "description": "in knots" + }, + "course": { + "type": "number" + }, + "address": { + "type": "string" + }, + "accuracy": { + "type": "number" + }, + "network": { + "type": "object", + "properties": {} + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "User": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "readonly": { + "type": "boolean" + }, + "administrator": { + "type": "boolean" + }, + "map": { + "type": "string" + }, + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + }, + "zoom": { + "type": "integer" + }, + "password": { + "type": "string" + }, + "twelveHourFormat": { + "type": "boolean" + }, + "coordinateFormat": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "expirationTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "deviceLimit": { + "type": "integer" + }, + "userLimit": { + "type": "integer" + }, + "deviceReadonly": { + "type": "boolean" + }, + "limitCommands": { + "type": "boolean" + }, + "poiLayer": { + "type": "string" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Server": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "registration": { + "type": "boolean" + }, + "readonly": { + "type": "boolean" + }, + "deviceReadonly": { + "type": "boolean" + }, + "limitCommands": { + "type": "boolean" + }, + "map": { + "type": "string" + }, + "bingKey": { + "type": "string" + }, + "mapUrl": { + "type": "string" + }, + "poiLayer": { + "type": "string" + }, + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + }, + "zoom": { + "type": "integer" + }, + "twelveHourFormat": { + "type": "boolean" + }, + "version": { + "type": "string" + }, + "forceSettings": { + "type": "boolean" + }, + "coordinateFormat": { + "type": "string" + }, + "openIdEnabled": { + "type": "boolean" + }, + "openIdForce": { + "type": "boolean" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Command": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "deviceId": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Device": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "uniqueId": { + "type": "string" + }, + "status": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "lastUpdate": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "positionId": { + "type": "integer" + }, + "groupId": { + "type": "integer" + }, + "phone": { + "type": "string" + }, + "model": { + "type": "string" + }, + "contact": { + "type": "string" + }, + "category": { + "type": "string" + }, + "geofenceIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Group": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Permission": { + "type": "object", + "properties": { + "userId": { + "type": "integer", + "description": "User Id, can be only first parameter" + }, + "deviceId": { + "type": "integer", + "description": "Device Id, can be first parameter or second only in combination with userId" + }, + "groupId": { + "type": "integer", + "description": "Group Id, can be first parameter or second only in combination with userId" + }, + "geofenceId": { + "type": "integer", + "description": "Geofence Id, can be second parameter only" + }, + "notificationId": { + "type": "integer", + "description": "Notification Id, can be second parameter only" + }, + "calendarId": { + "type": "integer", + "description": "Calendar Id, can be second parameter only and only in combination with userId" + }, + "attributeId": { + "type": "integer", + "description": "Computed Attribute Id, can be second parameter only" + }, + "driverId": { + "type": "integer", + "description": "Driver Id, can be second parameter only" + }, + "managedUserId": { + "type": "integer", + "description": "User Id, can be second parameter only and only in combination with userId" + } + }, + "description": "This is a permission map that contain two object indexes. It is used to link/unlink objects. Order is important. Example: { deviceId:8, geofenceId: 16 }" + }, + "CommandType": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + }, + "Geofence": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "area": { + "type": "string" + }, + "calendarId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Notification": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "always": { + "type": "boolean" + }, + "web": { + "type": "boolean" + }, + "mail": { + "type": "boolean" + }, + "sms": { + "type": "boolean" + }, + "calendarId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "NotificationType": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + }, + "Event": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "eventTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "deviceId": { + "type": "integer" + }, + "positionId": { + "type": "integer" + }, + "geofenceId": { + "type": "integer" + }, + "maintenanceId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "ReportSummary": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "deviceName": { + "type": "string" + }, + "maxSpeed": { + "type": "number", + "description": "in knots" + }, + "averageSpeed": { + "type": "number", + "description": "in knots" + }, + "distance": { + "type": "number", + "description": "in meters" + }, + "spentFuel": { + "type": "number", + "description": "in liters" + }, + "engineHours": { + "type": "integer" + } + } + }, + "ReportTrips": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "deviceName": { + "type": "string" + }, + "maxSpeed": { + "type": "number", + "description": "in knots" + }, + "averageSpeed": { + "type": "number", + "description": "in knots" + }, + "distance": { + "type": "number", + "description": "in meters" + }, + "spentFuel": { + "type": "number", + "description": "in liters" + }, + "duration": { + "type": "integer" + }, + "startTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "startAddress": { + "type": "string" + }, + "startLat": { + "type": "number" + }, + "startLon": { + "type": "number" + }, + "endTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "endAddress": { + "type": "string" + }, + "endLat": { + "type": "number" + }, + "endLon": { + "type": "number" + }, + "driverUniqueId": { + "type": "integer" + }, + "driverName": { + "type": "string" + } + } + }, + "ReportStops": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "deviceName": { + "type": "string" + }, + "duration": { + "type": "integer" + }, + "startTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "address": { + "type": "string" + }, + "lat": { + "type": "number" + }, + "lon": { + "type": "number" + }, + "endTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "spentFuel": { + "type": "number", + "description": "in liters" + }, + "engineHours": { + "type": "integer" + } + } + }, + "Statistics": { + "type": "object", + "properties": { + "captureTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "activeUsers": { + "type": "integer" + }, + "activeDevices": { + "type": "integer" + }, + "requests": { + "type": "integer" + }, + "messagesReceived": { + "type": "integer" + }, + "messagesStored": { + "type": "integer" + } + } + }, + "DeviceAccumulators": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "totalDistance": { + "type": "number", + "description": "in meters" + }, + "hours": { + "type": "number" + } + } + }, + "Calendar": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "data": { + "type": "string", + "description": "base64 encoded in iCalendar format" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Attribute": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "attribute": { + "type": "string" + }, + "expression": { + "type": "string" + }, + "type": { + "type": "string", + "description": "String|Number|Boolean" + } + } + }, + "Driver": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "uniqueId": { + "type": "string" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Maintenance": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "start": { + "type": "number" + }, + "period": { + "type": "number" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + } + }, + "parameters": { + "entityId": { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + }, + "all": { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + "refresh": { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + }, + "userId": { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + "deviceId": { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + "groupId": { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + "deviceIdArray": { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "groupIdArray": { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "fromTime": { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + "toTime": { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + }, + "requestBodies": { + "Device": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "Permission": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Permission" + } + } + }, + "required": true + }, + "Group": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + }, + "required": true + }, + "User": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": true + }, + "Geofence": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + }, + "required": true + }, + "Calendar": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + }, + "required": true + }, + "Attribute": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + }, + "required": true + }, + "Driver": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + }, + "required": true + }, + "Command": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "Notification": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + }, + "required": true + }, + "Maintenance": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + }, + "required": true + } + }, + "securitySchemes": { + "basicAuth": { + "type": "http", + "description": "Basic HTTP authorization with _email_ and _password_", + "scheme": "basic" + } + } + } +} -- cgit v1.2.3 From 256492e692ee881842782d5dc0932a4b742c75a8 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 17:31:34 +0100 Subject: Create user defaults method --- .../org/traccar/api/resource/UserResource.java | 235 ++++++++++---------- .../org/traccar/api/security/LoginService.java | 242 +++++++++++---------- .../java/org/traccar/helper/model/UserUtil.java | 146 +++++++------ traccar-web | 2 +- 4 files changed, 317 insertions(+), 308 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index e41ebbe61..57df3481e 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -1,120 +1,115 @@ -/* - * 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. - * 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.api.resource; - -import org.traccar.api.BaseObjectResource; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.helper.LogAction; -import org.traccar.helper.model.UserUtil; -import org.traccar.model.ManagedUser; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.Collection; -import java.util.Date; - -@Path("users") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class UserResource extends BaseObjectResource { - - @Inject - private Config config; - - public UserResource() { - super(User.class); - } - - @GET - public Collection get(@QueryParam("userId") long userId) throws StorageException { - if (userId > 0) { - permissionsService.checkUser(getUserId(), userId); - return storage.getObjects(baseClass, new Request( - new Columns.All(), - new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); - } else if (permissionsService.notAdmin(getUserId())) { - return storage.getObjects(baseClass, new Request( - new Columns.All(), - new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())); - } else { - return storage.getObjects(baseClass, new Request(new Columns.All())); - } - } - - @Override - @PermitAll - @POST - public Response add(User entity) throws StorageException { - User currentUser = getUserId() > 0 ? permissionsService.getUser(getUserId()) : null; - if (currentUser == null || !currentUser.getAdministrator()) { - permissionsService.checkUserUpdate(getUserId(), new User(), entity); - if (currentUser != null && currentUser.getUserLimit() != 0) { - int userLimit = currentUser.getUserLimit(); - if (userLimit > 0) { - int userCount = storage.getObjects(baseClass, new Request( - new Columns.All(), - new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())) - .size(); - if (userCount >= userLimit) { - throw new SecurityException("Manager user limit reached"); - } - } - } else { - if (!permissionsService.getServer().getRegistration()) { - throw new SecurityException("Registration disabled"); - } - entity.setDeviceLimit(config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); - int expirationDays = config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); - if (expirationDays > 0) { - entity.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); - } - } - } - - if (UserUtil.isEmpty(storage)) { - entity.setAdministrator(true); - } - - entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); - storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), - new Condition.Equals("id", entity.getId()))); - - LogAction.create(getUserId(), entity); - - if (currentUser != null && currentUser.getUserLimit() != 0) { - storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); - LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); - } - return Response.ok(entity).build(); - } - -} +/* + * 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. + * 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.api.resource; + +import org.traccar.api.BaseObjectResource; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.helper.LogAction; +import org.traccar.helper.model.UserUtil; +import org.traccar.model.ManagedUser; +import org.traccar.model.Permission; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.security.PermitAll; +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Collection; + +@Path("users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class UserResource extends BaseObjectResource { + + @Inject + private Config config; + + public UserResource() { + super(User.class); + } + + @GET + public Collection get(@QueryParam("userId") long userId) throws StorageException { + if (userId > 0) { + permissionsService.checkUser(getUserId(), userId); + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); + } else if (permissionsService.notAdmin(getUserId())) { + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())); + } else { + return storage.getObjects(baseClass, new Request(new Columns.All())); + } + } + + @Override + @PermitAll + @POST + public Response add(User entity) throws StorageException { + User currentUser = getUserId() > 0 ? permissionsService.getUser(getUserId()) : null; + if (currentUser == null || !currentUser.getAdministrator()) { + permissionsService.checkUserUpdate(getUserId(), new User(), entity); + if (currentUser != null && currentUser.getUserLimit() != 0) { + int userLimit = currentUser.getUserLimit(); + if (userLimit > 0) { + int userCount = storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())) + .size(); + if (userCount >= userLimit) { + throw new SecurityException("Manager user limit reached"); + } + } + } else { + if (!permissionsService.getServer().getRegistration()) { + throw new SecurityException("Registration disabled"); + } + UserUtil.setUserDefaults(entity, config); + } + } + + if (UserUtil.isEmpty(storage)) { + entity.setAdministrator(true); + } + + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", entity.getId()))); + + LogAction.create(getUserId(), entity); + + if (currentUser != null && currentUser.getUserLimit() != 0) { + storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); + LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); + } + return Response.ok(entity).build(); + } + +} diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 7b51667c8..99539e50d 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -1,119 +1,123 @@ -/* - * 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.api.security; - -import org.traccar.api.signature.TokenManager; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.LdapProvider; -import org.traccar.model.User; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; -import java.security.GeneralSecurityException; - -@Singleton -public class LoginService { - - private final Storage storage; - private final TokenManager tokenManager; - private final LdapProvider ldapProvider; - - private final String serviceAccountToken; - private final boolean forceLdap; - - @Inject - public LoginService( - Config config, Storage storage, TokenManager tokenManager, @Nullable LdapProvider ldapProvider) { - this.storage = storage; - this.tokenManager = tokenManager; - this.ldapProvider = ldapProvider; - serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); - forceLdap = config.getBoolean(Keys.LDAP_FORCE); - } - - public User login(String token) throws StorageException, GeneralSecurityException, IOException { - if (serviceAccountToken != null && serviceAccountToken.equals(token)) { - return new ServiceAccountUser(); - } - long userId = tokenManager.verifyToken(token); - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", userId))); - if (user != null) { - checkUserEnabled(user); - } - return user; - } - - public User login(String email, String password) throws StorageException { - email = email.trim(); - User user = storage.getObject(User.class, new Request( - new Columns.All(), - new Condition.Or( - new Condition.Equals("email", email), - new Condition.Equals("login", email)))); - if (user != null) { - if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) - || !forceLdap && user.isPasswordValid(password)) { - checkUserEnabled(user); - return user; - } - } else { - if (ldapProvider != null && ldapProvider.login(email, password)) { - user = ldapProvider.getUser(email); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - checkUserEnabled(user); - return user; - } - } - return null; - } - - public User login(String email, String name, Boolean administrator) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.All(), - new Condition.Equals("email", email))); - - if (user != null) { - checkUserEnabled(user); - return user; - } else { - user = new User(); - user.setName(name); - user.setEmail(email); - user.setFixedEmail(true); - user.setAdministrator(administrator); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - checkUserEnabled(user); - return user; - } - } - - private void checkUserEnabled(User user) throws SecurityException { - if (user == null) { - throw new SecurityException("Unknown account"); - } - user.checkDisabled(); - } - -} +/* + * 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.api.security; + +import org.traccar.api.signature.TokenManager; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.database.LdapProvider; +import org.traccar.helper.model.UserUtil; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.IOException; +import java.security.GeneralSecurityException; + +@Singleton +public class LoginService { + + private final Config config; + private final Storage storage; + private final TokenManager tokenManager; + private final LdapProvider ldapProvider; + + private final String serviceAccountToken; + private final boolean forceLdap; + + @Inject + public LoginService( + Config config, Storage storage, TokenManager tokenManager, @Nullable LdapProvider ldapProvider) { + this.storage = storage; + this.config = config; + this.tokenManager = tokenManager; + this.ldapProvider = ldapProvider; + serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); + forceLdap = config.getBoolean(Keys.LDAP_FORCE); + } + + public User login(String token) throws StorageException, GeneralSecurityException, IOException { + if (serviceAccountToken != null && serviceAccountToken.equals(token)) { + return new ServiceAccountUser(); + } + long userId = tokenManager.verifyToken(token); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", userId))); + if (user != null) { + checkUserEnabled(user); + } + return user; + } + + public User login(String email, String password) throws StorageException { + email = email.trim(); + User user = storage.getObject(User.class, new Request( + new Columns.All(), + new Condition.Or( + new Condition.Equals("email", email), + new Condition.Equals("login", email)))); + if (user != null) { + if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) + || !forceLdap && user.isPasswordValid(password)) { + checkUserEnabled(user); + return user; + } + } else { + if (ldapProvider != null && ldapProvider.login(email, password)) { + user = ldapProvider.getUser(email); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + return null; + } + + public User login(String email, String name, Boolean administrator) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.All(), + new Condition.Equals("email", email))); + + if (user != null) { + checkUserEnabled(user); + return user; + } else { + user = new User(); + UserUtil.setUserDefaults(user, config); + user.setName(name); + user.setEmail(email); + user.setFixedEmail(true); + user.setAdministrator(administrator); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + + private void checkUserEnabled(User user) throws SecurityException { + if (user == null) { + throw new SecurityException("Unknown account"); + } + user.checkDisabled(); + } + +} diff --git a/src/main/java/org/traccar/helper/model/UserUtil.java b/src/main/java/org/traccar/helper/model/UserUtil.java index 9f93afeae..0dc355114 100644 --- a/src/main/java/org/traccar/helper/model/UserUtil.java +++ b/src/main/java/org/traccar/helper/model/UserUtil.java @@ -1,68 +1,78 @@ -/* - * 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.helper.model; - -import org.traccar.model.Server; -import org.traccar.model.User; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Order; -import org.traccar.storage.query.Request; - -import java.util.TimeZone; - -public final class UserUtil { - - private UserUtil() { - } - - public static boolean isEmpty(Storage storage) throws StorageException { - return storage.getObjects(User.class, new Request( - new Columns.Include("id"), - new Order("id", false, 1))).isEmpty(); - } - - public static String getDistanceUnit(Server server, User user) { - return lookupStringAttribute(server, user, "distanceUnit", "km"); - } - - public static String getSpeedUnit(Server server, User user) { - return lookupStringAttribute(server, user, "speedUnit", "kn"); - } - - public static String getVolumeUnit(Server server, User user) { - return lookupStringAttribute(server, user, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(Server server, User user) { - String timezone = lookupStringAttribute(server, user, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - - private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { - String preference; - String serverPreference = server.getString(key); - String userPreference = user.getString(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - -} +/* + * 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.helper.model; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Server; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; + +import java.util.Date; +import java.util.TimeZone; + +public final class UserUtil { + + private UserUtil() { + } + + public static boolean isEmpty(Storage storage) throws StorageException { + return storage.getObjects(User.class, new Request( + new Columns.Include("id"), + new Order("id", false, 1))).isEmpty(); + } + + public static String getDistanceUnit(Server server, User user) { + return lookupStringAttribute(server, user, "distanceUnit", "km"); + } + + public static String getSpeedUnit(Server server, User user) { + return lookupStringAttribute(server, user, "speedUnit", "kn"); + } + + public static String getVolumeUnit(Server server, User user) { + return lookupStringAttribute(server, user, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(Server server, User user) { + String timezone = lookupStringAttribute(server, user, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { + String preference; + String serverPreference = server.getString(key); + String userPreference = user.getString(key); + if (server.getForceSettings()) { + preference = serverPreference != null ? serverPreference : userPreference; + } else { + preference = userPreference != null ? userPreference : serverPreference; + } + return preference != null ? preference : defaultValue; + } + + public static void setUserDefaults(User user, Config config) { + user.setDeviceLimit(config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); + int expirationDays = config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); + if (expirationDays > 0) { + user.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); + } + } +} diff --git a/traccar-web b/traccar-web index 506dd66b7..87e9c7dd5 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 506dd66b793803a24a2872e242482f263087df52 +Subproject commit 87e9c7dd5159c1d08368bfafa30fed9ae811933c -- cgit v1.2.3 From c6de74b4bb0f116b0fcbbb65b20296970597b652 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 17:39:06 +0100 Subject: Fixing my line endings, thanks Windows --- .../org/traccar/api/resource/SessionResource.java | 376 +- .../org/traccar/api/resource/UserResource.java | 230 +- .../org/traccar/api/security/LoginService.java | 246 +- .../java/org/traccar/database/OpenIdProvider.java | 326 +- .../java/org/traccar/helper/model/UserUtil.java | 156 +- swagger.json | 7052 ++++++++++---------- 6 files changed, 4193 insertions(+), 4193 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 8240a8a6f..94a6a4595 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -1,188 +1,188 @@ -/* - * 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. - * 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.api.resource; - -import org.traccar.api.BaseResource; -import org.traccar.api.security.LoginService; -import org.traccar.api.signature.TokenManager; -import org.traccar.database.OpenIdProvider; -import org.traccar.helper.DataConverter; -import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; -import org.traccar.model.User; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import com.nimbusds.oauth2.sdk.ParseException; -import javax.annotation.Nullable; -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.util.Date; -import java.net.URI; - -@Path("session") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_FORM_URLENCODED) -public class SessionResource extends BaseResource { - - public static final String USER_ID_KEY = "userId"; - public static final String USER_COOKIE_KEY = "user"; - public static final String PASS_COOKIE_KEY = "password"; - - @Inject - private LoginService loginService; - - @Inject - @Nullable - private OpenIdProvider openIdProvider; - - @Inject - private TokenManager tokenManager; - - @Context - private HttpServletRequest request; - - @PermitAll - @GET - public User get(@QueryParam("token") String token) throws StorageException, IOException, GeneralSecurityException { - - if (token != null) { - User user = loginService.login(token); - if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } - } - - Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY); - if (userId == null) { - - Cookie[] cookies = request.getCookies(); - String email = null, password = null; - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookie.getName().equals(USER_COOKIE_KEY)) { - byte[] emailBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); - email = new String(emailBytes, StandardCharsets.UTF_8); - } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { - byte[] passwordBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); - password = new String(passwordBytes, StandardCharsets.UTF_8); - } - } - } - if (email != null && password != null) { - User user = loginService.login(email, password); - if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } - } - - } else { - - User user = permissionsService.getUser(userId); - if (user != null) { - return user; - } - - } - - throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); - } - - @Path("{id}") - @GET - public User get(@PathParam("id") long userId) throws StorageException { - permissionsService.checkUser(getUserId(), userId); - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", userId))); - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } - - @PermitAll - @POST - public User add( - @FormParam("email") String email, @FormParam("password") String password) throws StorageException { - User user = loginService.login(email, password); - if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - return user; - } else { - LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); - throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); - } - } - - @DELETE - public Response remove() { - LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); - request.getSession().removeAttribute(USER_ID_KEY); - return Response.noContent().build(); - } - - @Path("token") - @POST - public String requestToken( - @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { - return tokenManager.generateToken(getUserId(), expiration); - } - - @PermitAll - @Path("openid/auth") - @GET - public Response openIdAuth() throws IOException { - return Response.seeOther(openIdProvider.createAuthUri()).build(); - } - - @PermitAll - @Path("openid/callback") - @GET - public Response requestToken() throws IOException, StorageException, ParseException, GeneralSecurityException { - StringBuilder requestUrl = new StringBuilder(request.getRequestURL().toString()); - String queryString = request.getQueryString(); - String requestUri = requestUrl.append('?').append(queryString).toString(); - - return Response.seeOther(openIdProvider.handleCallback(URI.create(requestUri), request)).build(); - } -} +/* + * 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. + * 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.api.resource; + +import org.traccar.api.BaseResource; +import org.traccar.api.security.LoginService; +import org.traccar.api.signature.TokenManager; +import org.traccar.database.OpenIdProvider; +import org.traccar.helper.DataConverter; +import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import com.nimbusds.oauth2.sdk.ParseException; +import javax.annotation.Nullable; +import javax.annotation.security.PermitAll; +import javax.inject.Inject; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.util.Date; +import java.net.URI; + +@Path("session") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_FORM_URLENCODED) +public class SessionResource extends BaseResource { + + public static final String USER_ID_KEY = "userId"; + public static final String USER_COOKIE_KEY = "user"; + public static final String PASS_COOKIE_KEY = "password"; + + @Inject + private LoginService loginService; + + @Inject + @Nullable + private OpenIdProvider openIdProvider; + + @Inject + private TokenManager tokenManager; + + @Context + private HttpServletRequest request; + + @PermitAll + @GET + public User get(@QueryParam("token") String token) throws StorageException, IOException, GeneralSecurityException { + + if (token != null) { + User user = loginService.login(token); + if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + } + + Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY); + if (userId == null) { + + Cookie[] cookies = request.getCookies(); + String email = null, password = null; + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equals(USER_COOKIE_KEY)) { + byte[] emailBytes = DataConverter.parseBase64( + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); + email = new String(emailBytes, StandardCharsets.UTF_8); + } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { + byte[] passwordBytes = DataConverter.parseBase64( + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); + password = new String(passwordBytes, StandardCharsets.UTF_8); + } + } + } + if (email != null && password != null) { + User user = loginService.login(email, password); + if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + } + + } else { + + User user = permissionsService.getUser(userId); + if (user != null) { + return user; + } + + } + + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); + } + + @Path("{id}") + @GET + public User get(@PathParam("id") long userId) throws StorageException { + permissionsService.checkUser(getUserId(), userId); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", userId))); + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + + @PermitAll + @POST + public User add( + @FormParam("email") String email, @FormParam("password") String password) throws StorageException { + User user = loginService.login(email, password); + if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } else { + LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); + throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); + } + } + + @DELETE + public Response remove() { + LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); + request.getSession().removeAttribute(USER_ID_KEY); + return Response.noContent().build(); + } + + @Path("token") + @POST + public String requestToken( + @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { + return tokenManager.generateToken(getUserId(), expiration); + } + + @PermitAll + @Path("openid/auth") + @GET + public Response openIdAuth() throws IOException { + return Response.seeOther(openIdProvider.createAuthUri()).build(); + } + + @PermitAll + @Path("openid/callback") + @GET + public Response requestToken() throws IOException, StorageException, ParseException, GeneralSecurityException { + StringBuilder requestUrl = new StringBuilder(request.getRequestURL().toString()); + String queryString = request.getQueryString(); + String requestUri = requestUrl.append('?').append(queryString).toString(); + + return Response.seeOther(openIdProvider.handleCallback(URI.create(requestUri), request)).build(); + } +} diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 57df3481e..1c58cec3c 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -1,115 +1,115 @@ -/* - * 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. - * 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.api.resource; - -import org.traccar.api.BaseObjectResource; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.helper.LogAction; -import org.traccar.helper.model.UserUtil; -import org.traccar.model.ManagedUser; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.Collection; - -@Path("users") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class UserResource extends BaseObjectResource { - - @Inject - private Config config; - - public UserResource() { - super(User.class); - } - - @GET - public Collection get(@QueryParam("userId") long userId) throws StorageException { - if (userId > 0) { - permissionsService.checkUser(getUserId(), userId); - return storage.getObjects(baseClass, new Request( - new Columns.All(), - new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); - } else if (permissionsService.notAdmin(getUserId())) { - return storage.getObjects(baseClass, new Request( - new Columns.All(), - new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())); - } else { - return storage.getObjects(baseClass, new Request(new Columns.All())); - } - } - - @Override - @PermitAll - @POST - public Response add(User entity) throws StorageException { - User currentUser = getUserId() > 0 ? permissionsService.getUser(getUserId()) : null; - if (currentUser == null || !currentUser.getAdministrator()) { - permissionsService.checkUserUpdate(getUserId(), new User(), entity); - if (currentUser != null && currentUser.getUserLimit() != 0) { - int userLimit = currentUser.getUserLimit(); - if (userLimit > 0) { - int userCount = storage.getObjects(baseClass, new Request( - new Columns.All(), - new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())) - .size(); - if (userCount >= userLimit) { - throw new SecurityException("Manager user limit reached"); - } - } - } else { - if (!permissionsService.getServer().getRegistration()) { - throw new SecurityException("Registration disabled"); - } - UserUtil.setUserDefaults(entity, config); - } - } - - if (UserUtil.isEmpty(storage)) { - entity.setAdministrator(true); - } - - entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); - storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), - new Condition.Equals("id", entity.getId()))); - - LogAction.create(getUserId(), entity); - - if (currentUser != null && currentUser.getUserLimit() != 0) { - storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); - LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); - } - return Response.ok(entity).build(); - } - -} +/* + * 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. + * 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.api.resource; + +import org.traccar.api.BaseObjectResource; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.helper.LogAction; +import org.traccar.helper.model.UserUtil; +import org.traccar.model.ManagedUser; +import org.traccar.model.Permission; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.security.PermitAll; +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Collection; + +@Path("users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class UserResource extends BaseObjectResource { + + @Inject + private Config config; + + public UserResource() { + super(User.class); + } + + @GET + public Collection get(@QueryParam("userId") long userId) throws StorageException { + if (userId > 0) { + permissionsService.checkUser(getUserId(), userId); + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); + } else if (permissionsService.notAdmin(getUserId())) { + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())); + } else { + return storage.getObjects(baseClass, new Request(new Columns.All())); + } + } + + @Override + @PermitAll + @POST + public Response add(User entity) throws StorageException { + User currentUser = getUserId() > 0 ? permissionsService.getUser(getUserId()) : null; + if (currentUser == null || !currentUser.getAdministrator()) { + permissionsService.checkUserUpdate(getUserId(), new User(), entity); + if (currentUser != null && currentUser.getUserLimit() != 0) { + int userLimit = currentUser.getUserLimit(); + if (userLimit > 0) { + int userCount = storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())) + .size(); + if (userCount >= userLimit) { + throw new SecurityException("Manager user limit reached"); + } + } + } else { + if (!permissionsService.getServer().getRegistration()) { + throw new SecurityException("Registration disabled"); + } + UserUtil.setUserDefaults(entity, config); + } + } + + if (UserUtil.isEmpty(storage)) { + entity.setAdministrator(true); + } + + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", entity.getId()))); + + LogAction.create(getUserId(), entity); + + if (currentUser != null && currentUser.getUserLimit() != 0) { + storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); + LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); + } + return Response.ok(entity).build(); + } + +} diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 99539e50d..d92f7ce15 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -1,123 +1,123 @@ -/* - * 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.api.security; - -import org.traccar.api.signature.TokenManager; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.LdapProvider; -import org.traccar.helper.model.UserUtil; -import org.traccar.model.User; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; -import java.security.GeneralSecurityException; - -@Singleton -public class LoginService { - - private final Config config; - private final Storage storage; - private final TokenManager tokenManager; - private final LdapProvider ldapProvider; - - private final String serviceAccountToken; - private final boolean forceLdap; - - @Inject - public LoginService( - Config config, Storage storage, TokenManager tokenManager, @Nullable LdapProvider ldapProvider) { - this.storage = storage; - this.config = config; - this.tokenManager = tokenManager; - this.ldapProvider = ldapProvider; - serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); - forceLdap = config.getBoolean(Keys.LDAP_FORCE); - } - - public User login(String token) throws StorageException, GeneralSecurityException, IOException { - if (serviceAccountToken != null && serviceAccountToken.equals(token)) { - return new ServiceAccountUser(); - } - long userId = tokenManager.verifyToken(token); - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", userId))); - if (user != null) { - checkUserEnabled(user); - } - return user; - } - - public User login(String email, String password) throws StorageException { - email = email.trim(); - User user = storage.getObject(User.class, new Request( - new Columns.All(), - new Condition.Or( - new Condition.Equals("email", email), - new Condition.Equals("login", email)))); - if (user != null) { - if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) - || !forceLdap && user.isPasswordValid(password)) { - checkUserEnabled(user); - return user; - } - } else { - if (ldapProvider != null && ldapProvider.login(email, password)) { - user = ldapProvider.getUser(email); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - checkUserEnabled(user); - return user; - } - } - return null; - } - - public User login(String email, String name, Boolean administrator) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.All(), - new Condition.Equals("email", email))); - - if (user != null) { - checkUserEnabled(user); - return user; - } else { - user = new User(); - UserUtil.setUserDefaults(user, config); - user.setName(name); - user.setEmail(email); - user.setFixedEmail(true); - user.setAdministrator(administrator); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - checkUserEnabled(user); - return user; - } - } - - private void checkUserEnabled(User user) throws SecurityException { - if (user == null) { - throw new SecurityException("Unknown account"); - } - user.checkDisabled(); - } - -} +/* + * 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.api.security; + +import org.traccar.api.signature.TokenManager; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.database.LdapProvider; +import org.traccar.helper.model.UserUtil; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.IOException; +import java.security.GeneralSecurityException; + +@Singleton +public class LoginService { + + private final Config config; + private final Storage storage; + private final TokenManager tokenManager; + private final LdapProvider ldapProvider; + + private final String serviceAccountToken; + private final boolean forceLdap; + + @Inject + public LoginService( + Config config, Storage storage, TokenManager tokenManager, @Nullable LdapProvider ldapProvider) { + this.storage = storage; + this.config = config; + this.tokenManager = tokenManager; + this.ldapProvider = ldapProvider; + serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); + forceLdap = config.getBoolean(Keys.LDAP_FORCE); + } + + public User login(String token) throws StorageException, GeneralSecurityException, IOException { + if (serviceAccountToken != null && serviceAccountToken.equals(token)) { + return new ServiceAccountUser(); + } + long userId = tokenManager.verifyToken(token); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", userId))); + if (user != null) { + checkUserEnabled(user); + } + return user; + } + + public User login(String email, String password) throws StorageException { + email = email.trim(); + User user = storage.getObject(User.class, new Request( + new Columns.All(), + new Condition.Or( + new Condition.Equals("email", email), + new Condition.Equals("login", email)))); + if (user != null) { + if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) + || !forceLdap && user.isPasswordValid(password)) { + checkUserEnabled(user); + return user; + } + } else { + if (ldapProvider != null && ldapProvider.login(email, password)) { + user = ldapProvider.getUser(email); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + return null; + } + + public User login(String email, String name, Boolean administrator) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.All(), + new Condition.Equals("email", email))); + + if (user != null) { + checkUserEnabled(user); + return user; + } else { + user = new User(); + UserUtil.setUserDefaults(user, config); + user.setName(name); + user.setEmail(email); + user.setFixedEmail(true); + user.setAdministrator(administrator); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + + private void checkUserEnabled(User user) throws SecurityException { + if (user == null) { + throw new SecurityException("Unknown account"); + } + user.checkDisabled(); + } + +} diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 22e5d6b50..5e5c54523 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -1,163 +1,163 @@ -/* - * Copyright 2023 Daniel Raper (me@danr.uk) - * - * 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.database; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.api.resource.SessionResource; -import org.traccar.api.security.LoginService; -import org.traccar.model.User; -import org.traccar.storage.StorageException; -import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; - -import java.net.URI; -import java.net.URISyntaxException; -import java.security.GeneralSecurityException; -import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import com.google.inject.Inject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nimbusds.oauth2.sdk.http.HTTPResponse; -import com.nimbusds.oauth2.sdk.AuthorizationCode; -import com.nimbusds.oauth2.sdk.ResponseType; -import com.nimbusds.oauth2.sdk.Scope; -import com.nimbusds.oauth2.sdk.AuthorizationGrant; -import com.nimbusds.oauth2.sdk.TokenRequest; -import com.nimbusds.oauth2.sdk.TokenResponse; -import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; -import com.nimbusds.oauth2.sdk.ParseException; -import com.nimbusds.oauth2.sdk.AuthorizationResponse; -import com.nimbusds.oauth2.sdk.auth.Secret; -import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; -import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; -import com.nimbusds.oauth2.sdk.token.BearerAccessToken; -import com.nimbusds.oauth2.sdk.id.State; -import com.nimbusds.oauth2.sdk.id.ClientID; -import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; -import com.nimbusds.openid.connect.sdk.Nonce; -import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; -import com.nimbusds.openid.connect.sdk.UserInfoResponse; -import com.nimbusds.openid.connect.sdk.UserInfoRequest; -import com.nimbusds.openid.connect.sdk.AuthenticationRequest; - -import com.nimbusds.openid.connect.sdk.claims.UserInfo; - -public class OpenIdProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); - - public final Boolean force; - private final ClientID clientId; - private final ClientAuthentication clientAuth; - private URI callbackUrl; - private URI authUrl; - private URI tokenUrl; - private URI userInfoUrl; - private URI baseUrl; - private final String adminGroup; - - private LoginService loginService; - - @Inject - public OpenIdProvider(Config config, LoginService loginService) { - this.loginService = loginService; - - force = config.getBoolean(Keys.OPENID_FORCE); - clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); - clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET))); - - try { - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, "")); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - } catch(URISyntaxException error) { - LOGGER.error("Invalid URIs provided in OpenID configuration"); - } - - adminGroup = config.getString(Keys.OPENID_ADMINGROUP); - } - - public URI createAuthUri() { - AuthenticationRequest.Builder request = new AuthenticationRequest.Builder( - new ResponseType("code"), - new Scope("openid", "profile", "email", "groups"), - clientId, - callbackUrl); - - return request.endpointURI(authUrl) - .state(new State()) - .build() - .toURI(); - } - - private OIDCTokenResponse getToken(AuthorizationCode code) throws IOException, ParseException, GeneralSecurityException { - AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); - TokenRequest tokenRequest = new TokenRequest(tokenUrl, clientAuth, codeGrant); - - HTTPResponse tokenResponse = tokenRequest.toHTTPRequest().send(); - TokenResponse token = OIDCTokenResponseParser.parse(tokenResponse); - if (!token.indicatesSuccess()) { - throw new GeneralSecurityException("Unable to authenticate with the OpenID Connect provider."); - } - - return (OIDCTokenResponse) token.toSuccessResponse(); - } - - private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException, GeneralSecurityException { - HTTPResponse httpResponse = new UserInfoRequest(userInfoUrl, token) - .toHTTPRequest() - .send(); - - UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse); - - if (!userInfoResponse.indicatesSuccess()) { - throw new GeneralSecurityException("Failed to access OpenID Connect user info endpoint. Please contact your administrator."); - } - - return userInfoResponse.toSuccessResponse().getUserInfo(); - } - - public URI handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, GeneralSecurityException { - AuthorizationResponse response = AuthorizationResponse.parse(requestUri); - - if (!response.indicatesSuccess()) { - throw new GeneralSecurityException(response.toErrorResponse().getErrorObject().getDescription()); - } - - AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); - - if (authCode == null) { - throw new GeneralSecurityException( "Malformed OpenID callback."); - } - - OIDCTokenResponse tokens = getToken(authCode); - - BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); - - UserInfo userInfo = getUserInfo(bearerToken); - - User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), userInfo.getStringListClaim("groups").contains(adminGroup)); - - request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - - return baseUrl; - } -} +/* + * Copyright 2023 Daniel Raper (me@danr.uk) + * + * 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.database; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.api.resource.SessionResource; +import org.traccar.api.security.LoginService; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; + +import java.net.URI; +import java.net.URISyntaxException; +import java.security.GeneralSecurityException; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import com.google.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nimbusds.oauth2.sdk.http.HTTPResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCode; +import com.nimbusds.oauth2.sdk.ResponseType; +import com.nimbusds.oauth2.sdk.Scope; +import com.nimbusds.oauth2.sdk.AuthorizationGrant; +import com.nimbusds.oauth2.sdk.TokenRequest; +import com.nimbusds.oauth2.sdk.TokenResponse; +import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant; +import com.nimbusds.oauth2.sdk.ParseException; +import com.nimbusds.oauth2.sdk.AuthorizationResponse; +import com.nimbusds.oauth2.sdk.auth.Secret; +import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; +import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; +import com.nimbusds.oauth2.sdk.token.BearerAccessToken; +import com.nimbusds.oauth2.sdk.id.State; +import com.nimbusds.oauth2.sdk.id.ClientID; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; +import com.nimbusds.openid.connect.sdk.Nonce; +import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; +import com.nimbusds.openid.connect.sdk.UserInfoResponse; +import com.nimbusds.openid.connect.sdk.UserInfoRequest; +import com.nimbusds.openid.connect.sdk.AuthenticationRequest; + +import com.nimbusds.openid.connect.sdk.claims.UserInfo; + +public class OpenIdProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); + + public final Boolean force; + private final ClientID clientId; + private final ClientAuthentication clientAuth; + private URI callbackUrl; + private URI authUrl; + private URI tokenUrl; + private URI userInfoUrl; + private URI baseUrl; + private final String adminGroup; + + private LoginService loginService; + + @Inject + public OpenIdProvider(Config config, LoginService loginService) { + this.loginService = loginService; + + force = config.getBoolean(Keys.OPENID_FORCE); + clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); + clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET))); + + try { + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, "")); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + } catch(URISyntaxException error) { + LOGGER.error("Invalid URIs provided in OpenID configuration"); + } + + adminGroup = config.getString(Keys.OPENID_ADMINGROUP); + } + + public URI createAuthUri() { + AuthenticationRequest.Builder request = new AuthenticationRequest.Builder( + new ResponseType("code"), + new Scope("openid", "profile", "email", "groups"), + clientId, + callbackUrl); + + return request.endpointURI(authUrl) + .state(new State()) + .build() + .toURI(); + } + + private OIDCTokenResponse getToken(AuthorizationCode code) throws IOException, ParseException, GeneralSecurityException { + AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); + TokenRequest tokenRequest = new TokenRequest(tokenUrl, clientAuth, codeGrant); + + HTTPResponse tokenResponse = tokenRequest.toHTTPRequest().send(); + TokenResponse token = OIDCTokenResponseParser.parse(tokenResponse); + if (!token.indicatesSuccess()) { + throw new GeneralSecurityException("Unable to authenticate with the OpenID Connect provider."); + } + + return (OIDCTokenResponse) token.toSuccessResponse(); + } + + private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException, GeneralSecurityException { + HTTPResponse httpResponse = new UserInfoRequest(userInfoUrl, token) + .toHTTPRequest() + .send(); + + UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse); + + if (!userInfoResponse.indicatesSuccess()) { + throw new GeneralSecurityException("Failed to access OpenID Connect user info endpoint. Please contact your administrator."); + } + + return userInfoResponse.toSuccessResponse().getUserInfo(); + } + + public URI handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, GeneralSecurityException { + AuthorizationResponse response = AuthorizationResponse.parse(requestUri); + + if (!response.indicatesSuccess()) { + throw new GeneralSecurityException(response.toErrorResponse().getErrorObject().getDescription()); + } + + AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); + + if (authCode == null) { + throw new GeneralSecurityException( "Malformed OpenID callback."); + } + + OIDCTokenResponse tokens = getToken(authCode); + + BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); + + UserInfo userInfo = getUserInfo(bearerToken); + + User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), userInfo.getStringListClaim("groups").contains(adminGroup)); + + request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + + return baseUrl; + } +} diff --git a/src/main/java/org/traccar/helper/model/UserUtil.java b/src/main/java/org/traccar/helper/model/UserUtil.java index 0dc355114..4b1c404f9 100644 --- a/src/main/java/org/traccar/helper/model/UserUtil.java +++ b/src/main/java/org/traccar/helper/model/UserUtil.java @@ -1,78 +1,78 @@ -/* - * 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.helper.model; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.Server; -import org.traccar.model.User; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Order; -import org.traccar.storage.query.Request; - -import java.util.Date; -import java.util.TimeZone; - -public final class UserUtil { - - private UserUtil() { - } - - public static boolean isEmpty(Storage storage) throws StorageException { - return storage.getObjects(User.class, new Request( - new Columns.Include("id"), - new Order("id", false, 1))).isEmpty(); - } - - public static String getDistanceUnit(Server server, User user) { - return lookupStringAttribute(server, user, "distanceUnit", "km"); - } - - public static String getSpeedUnit(Server server, User user) { - return lookupStringAttribute(server, user, "speedUnit", "kn"); - } - - public static String getVolumeUnit(Server server, User user) { - return lookupStringAttribute(server, user, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(Server server, User user) { - String timezone = lookupStringAttribute(server, user, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - - private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { - String preference; - String serverPreference = server.getString(key); - String userPreference = user.getString(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - - public static void setUserDefaults(User user, Config config) { - user.setDeviceLimit(config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); - int expirationDays = config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); - if (expirationDays > 0) { - user.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); - } - } -} +/* + * 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.helper.model; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Server; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; + +import java.util.Date; +import java.util.TimeZone; + +public final class UserUtil { + + private UserUtil() { + } + + public static boolean isEmpty(Storage storage) throws StorageException { + return storage.getObjects(User.class, new Request( + new Columns.Include("id"), + new Order("id", false, 1))).isEmpty(); + } + + public static String getDistanceUnit(Server server, User user) { + return lookupStringAttribute(server, user, "distanceUnit", "km"); + } + + public static String getSpeedUnit(Server server, User user) { + return lookupStringAttribute(server, user, "speedUnit", "kn"); + } + + public static String getVolumeUnit(Server server, User user) { + return lookupStringAttribute(server, user, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(Server server, User user) { + String timezone = lookupStringAttribute(server, user, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { + String preference; + String serverPreference = server.getString(key); + String userPreference = user.getString(key); + if (server.getForceSettings()) { + preference = serverPreference != null ? serverPreference : userPreference; + } else { + preference = userPreference != null ? userPreference : serverPreference; + } + return preference != null ? preference : defaultValue; + } + + public static void setUserDefaults(User user, Config config) { + user.setDeviceLimit(config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); + int expirationDays = config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); + if (expirationDays > 0) { + user.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); + } + } +} diff --git a/swagger.json b/swagger.json index 5a7349da8..cbdc9effd 100644 --- a/swagger.json +++ b/swagger.json @@ -1,3526 +1,3526 @@ -{ - "openapi": "3.0.1", - "info": { - "title": "Traccar", - "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", - "url": "https://www.traccar.org/", - "email": "support@traccar.org" - }, - "license": { - "name": "Apache 2.0", - "url": "https://www.apache.org/licenses/LICENSE-2.0.html" - } - }, - "servers": [ - { - "url": "https://demo.traccar.org/api", - "description": "Demo Server 1" - }, - { - "url": "https://demo2.traccar.org/api", - "description": "Demo Server 2" - }, - { - "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" - }, - { - "url": "http://{host}:{port}/api", - "description": "Other Server", - "variables": { - "host": { - "default": "localhost" - }, - "port": { - "enum": [ - "8082", - "80" - ], - "default": "8082" - } - } - } - ], - "security": [ - { - "basicAuth": [] - } - ], - "tags": [ - { - "name": "Server", - "description": "Server information" - }, - { - "name": "Session", - "description": "User session management" - }, - { - "name": "Devices", - "description": "Device management" - }, - { - "name": "Groups", - "description": "Group management" - }, - { - "name": "Users", - "description": "User management" - }, - { - "name": "Permissions", - "description": "User permissions and other object linking" - }, - { - "name": "Positions", - "description": "Retrieving raw location information" - }, - { - "name": "Events", - "description": "Retrieving event information" - }, - { - "name": "Reports", - "description": "Reports generation" - }, - { - "name": "Notifications", - "description": "User notifications management" - }, - { - "name": "Geofences", - "description": "Geofence management" - }, - { - "name": "Commands", - "description": "Sending commands to devices and stored command management" - }, - { - "name": "Attributes", - "description": "Computed attributes management" - }, - { - "name": "Drivers", - "description": "Drivers management" - }, - { - "name": "Maintenance", - "description": "Maintenance management" - }, - { - "name": "Calendars", - "description": "Calendar management" - }, - { - "name": "Statistics", - "description": "Retrieving server statistics" - } - ], - "paths": { - "/commands": { - "get": { - "summary": "Fetch a list of Saved Commands", - "tags": [ - "Commands" - ], - "description": "Without params, it returns a list of Saved Commands the user has access to", - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Command" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Saved Command", - "tags": [ - "Commands" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/commands/{id}": { - "put": { - "summary": "Update a Saved Command", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Saved Command", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/commands/send": { - "get": { - "summary": "Fetch a list of Saved Commands supported by Device at the moment", - "description": "Return a list of saved commands linked to Device and its groups, filtered by current Device protocol support", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Command" - } - } - } - } - }, - "400": { - "description": "Could happen when the user doesn't have permission for the device", - "content": {} - } - } - }, - "post": { - "summary": "Dispatch commands to device", - "description": "Dispatch a new command or Saved Command if _body.id_ set", - "tags": [ - "Commands" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Command sent", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - }, - "202": { - "description": "Command queued", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - } - }, - "400": { - "description": "Could happen when the user doesn't have permission or an incorrect command _type_ for the device", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/commands/types": { - "get": { - "summary": "Fetch a list of available Commands for the Device or all possible Commands if Device ommited", - "tags": [ - "Commands" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "description": "Internal device identifier. Only works if device has already reported some locations", - "schema": { - "type": "integer" - } - }, - { - "name": "protocol", - "in": "query", - "description": "Protocol name. Can be used instead of device id", - "schema": { - "type": "string" - } - }, - { - "name": "textChannel", - "in": "query", - "description": "When `true` return SMS commands. If not specified or `false` return data commands", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CommandType" - } - } - } - } - }, - "400": { - "description": "Could happen when trying to fetch from a device the user does not have permission", - "content": {} - } - } - } - }, - "/devices": { - "get": { - "summary": "Fetch a list of Devices", - "description": "Without any params, returns a list of the user's devices", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "id", - "in": "query", - "description": "To fetch one or more devices. Multiple params can be passed like `id=31&id=42`", - "schema": { - "type": "integer" - } - }, - { - "name": "uniqueId", - "in": "query", - "description": "To fetch one or more devices. Multiple params can be passed like `uniqueId=333331&uniqieId=44442`", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Device" - } - } - } - } - }, - "400": { - "description": "No permission", - "content": {} - } - } - }, - "post": { - "summary": "Create a Device", - "tags": [ - "Devices" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/devices/{id}": { - "put": { - "summary": "Update a Device", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Device", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/devices/{id}/accumulators": { - "put": { - "summary": "Update total distance and hours of the Device", - "tags": [ - "Devices" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeviceAccumulators" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/groups": { - "get": { - "summary": "Fetch a list of Groups", - "description": "Without any params, returns a list of the Groups the user belongs to", - "tags": [ - "Groups" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Group" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Group", - "tags": [ - "Groups" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - } - }, - "400": { - "description": "No permission", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/groups/{id}": { - "put": { - "summary": "Update a Group", - "tags": [ - "Groups" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Group", - "tags": [ - "Groups" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/permissions": { - "post": { - "summary": "Link an Object to another Object", - "tags": [ - "Permissions" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Permission" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content", - "content": {} - }, - "400": { - "description": "No permission", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Unlink an Object from another Object", - "tags": [ - "Permissions" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Permission" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content", - "content": {} - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/positions": { - "get": { - "summary": "Fetches a list of Positions", - "description": "We strongly recommend using [Traccar WebSocket API](https://www.traccar.org/traccar-api/) instead of periodically polling positions endpoint. Without any params, it returns a list of last known positions for all the user's Devices. _from_ and _to_ fields are not required with _id_.", - "tags": [ - "Positions" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "description": "_deviceId_ is optional, but requires the _from_ and _to_ parameters when used", - "schema": { - "type": "integer" - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "id", - "in": "query", - "description": "To fetch one or more positions. Multiple params can be passed like `id=31&id=42`", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - }, - "text/csv": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - }, - "application/gpx+xml": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - } - } - } - } - } - }, - "/server": { - "get": { - "summary": "Fetch Server information", - "tags": [ - "Server" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Server" - } - } - } - } - } - }, - "put": { - "summary": "Update Server information", - "tags": [ - "Server" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Server" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Server" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/session": { - "get": { - "summary": "Fetch Session information", - "tags": [ - "Session" - ], - "parameters": [ - { - "name": "token", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "404": { - "description": "Not Found", - "content": {} - } - } - }, - "post": { - "summary": "Create a new Session", - "tags": [ - "Session" - ], - "requestBody": { - "content": { - "application/x-www-form-urlencoded": { - "schema": { - "required": [ - "email", - "password" - ], - "properties": { - "email": { - "type": "string" - }, - "password": { - "type": "string", - "format": "password" - } - } - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": {} - } - } - }, - "delete": { - "summary": "Close the Session", - "tags": [ - "Session" - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/session/openid/auth": { - "get": { - "summary": "Fetch Session information", - "tags": [ - "Session" - ], - "parameters": [ - { - } - ], - "responses": { - "303": { - "description": "Redirect to OpenID Connect identity provider", - "content": { } - } - } - } - }, - "/session/openid/callback": { - "get": { - "summary": "OpenID Callback", - "tags": [ - "Session" - ], - "parameters": [ - { - } - ], - "responses": { - "303": { - "description": "Successful authentication, redirect to homepage", - "content": { } - } - } - } - }, - "/users": { - "get": { - "summary": "Fetch a list of Users", - "tags": [ - "Users" - ], - "parameters": [ - { - "name": "userId", - "in": "query", - "description": "Can only be used by admin or manager users", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "400": { - "description": "No Permission", - "content": {} - } - } - }, - "post": { - "summary": "Create a User", - "tags": [ - "Users" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/users/{id}": { - "put": { - "summary": "Update a User", - "tags": [ - "Users" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a User", - "tags": [ - "Users" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/notifications": { - "get": { - "summary": "Fetch a list of Notifications", - "description": "Without params, it returns a list of Notifications the user has access to", - "tags": [ - "Notifications" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Notification" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Notification", - "tags": [ - "Notifications" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/notifications/{id}": { - "put": { - "summary": "Update a Notification", - "tags": [ - "Notifications" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Notification", - "tags": [ - "Notifications" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/notifications/types": { - "get": { - "summary": "Fetch a list of available Notification types", - "tags": [ - "Notifications" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationType" - } - } - } - } - } - } - } - }, - "/notifications/test": { - "post": { - "summary": "Send test notification to current user via Email and SMS", - "tags": [ - "Notifications" - ], - "responses": { - "204": { - "description": "Successful sending", - "content": {} - }, - "400": { - "description": "Could happen if sending has failed", - "content": {} - } - } - } - }, - "/geofences": { - "get": { - "summary": "Fetch a list of Geofences", - "description": "Without params, it returns a list of Geofences the user has access to", - "tags": [ - "Geofences" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Geofence" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Geofence", - "tags": [ - "Geofences" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/geofences/{id}": { - "put": { - "summary": "Update a Geofence", - "tags": [ - "Geofences" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Geofence", - "tags": [ - "Geofences" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/events/{id}": { - "get": { - "tags": [ - "Events" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Event" - } - } - } - } - } - } - }, - "/reports/route": { - "get": { - "summary": "Fetch a list of Positions within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Position" - } - } - } - } - } - } - } - }, - "/reports/events": { - "get": { - "summary": "Fetch a list of Events within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "type", - "in": "query", - "description": "% can be used to return events of all types", - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Event" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Event" - } - } - } - } - } - } - } - }, - "/reports/summary": { - "get": { - "summary": "Fetch a list of ReportSummary within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportSummary" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportSummary" - } - } - } - } - } - } - } - }, - "/reports/trips": { - "get": { - "summary": "Fetch a list of ReportTrips within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportTrips" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportTrips" - } - } - } - } - } - } - } - }, - "/reports/stops": { - "get": { - "summary": "Fetch a list of ReportStops within the time period for the Devices or Groups", - "description": "At least one _deviceId_ or one _groupId_ must be passed", - "tags": [ - "Reports" - ], - "parameters": [ - { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportStops" - } - } - }, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReportStops" - } - } - } - } - } - } - } - }, - "/statistics": { - "get": { - "summary": "Fetch server Statistics", - "tags": [ - "Statistics" - ], - "parameters": [ - { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Statistics" - } - } - } - } - } - } - } - }, - "/calendars": { - "get": { - "summary": "Fetch a list of Calendars", - "description": "Without params, it returns a list of Calendars the user has access to", - "tags": [ - "Calendars" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Calendar" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Calendar", - "tags": [ - "Calendars" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/calendars/{id}": { - "put": { - "summary": "Update a Calendar", - "tags": [ - "Calendars" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Calendar", - "tags": [ - "Calendars" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/attributes/computed": { - "get": { - "summary": "Fetch a list of Attributes", - "description": "Without params, it returns a list of Attributes the user has access to", - "tags": [ - "Attributes" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Attribute" - } - } - } - } - } - } - }, - "post": { - "summary": "Create an Attribute", - "tags": [ - "Attributes" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/attributes/computed/{id}": { - "put": { - "summary": "Update an Attribute", - "tags": [ - "Attributes" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete an Attribute", - "tags": [ - "Attributes" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/drivers": { - "get": { - "summary": "Fetch a list of Drivers", - "description": "Without params, it returns a list of Drivers the user has access to", - "tags": [ - "Drivers" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Driver" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Driver", - "tags": [ - "Drivers" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/drivers/{id}": { - "put": { - "summary": "Update a Driver", - "tags": [ - "Drivers" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Driver", - "tags": [ - "Drivers" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - }, - "/maintenance": { - "get": { - "summary": "Fetch a list of Maintenance", - "description": "Without params, it returns a list of Maintenance the user has access to", - "tags": [ - "Maintenance" - ], - "parameters": [ - { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Maintenance" - } - } - } - } - } - } - }, - "post": { - "summary": "Create a Maintenance", - "tags": [ - "Maintenance" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - } - }, - "/maintenance/{id}": { - "put": { - "summary": "Update a Maintenance", - "tags": [ - "Maintenance" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - } - } - }, - "x-codegen-request-body-name": "body" - }, - "delete": { - "summary": "Delete a Maintenance", - "tags": [ - "Maintenance" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "content": {} - } - } - } - } - }, - "components": { - "schemas": { - "Position": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "deviceId": { - "type": "integer" - }, - "protocol": { - "type": "string" - }, - "deviceTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "fixTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "serverTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "outdated": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - }, - "latitude": { - "type": "number" - }, - "longitude": { - "type": "number" - }, - "altitude": { - "type": "number" - }, - "speed": { - "type": "number", - "description": "in knots" - }, - "course": { - "type": "number" - }, - "address": { - "type": "string" - }, - "accuracy": { - "type": "number" - }, - "network": { - "type": "object", - "properties": {} - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "User": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "email": { - "type": "string" - }, - "phone": { - "type": "string" - }, - "readonly": { - "type": "boolean" - }, - "administrator": { - "type": "boolean" - }, - "map": { - "type": "string" - }, - "latitude": { - "type": "number" - }, - "longitude": { - "type": "number" - }, - "zoom": { - "type": "integer" - }, - "password": { - "type": "string" - }, - "twelveHourFormat": { - "type": "boolean" - }, - "coordinateFormat": { - "type": "string" - }, - "disabled": { - "type": "boolean" - }, - "expirationTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "deviceLimit": { - "type": "integer" - }, - "userLimit": { - "type": "integer" - }, - "deviceReadonly": { - "type": "boolean" - }, - "limitCommands": { - "type": "boolean" - }, - "poiLayer": { - "type": "string" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Server": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "registration": { - "type": "boolean" - }, - "readonly": { - "type": "boolean" - }, - "deviceReadonly": { - "type": "boolean" - }, - "limitCommands": { - "type": "boolean" - }, - "map": { - "type": "string" - }, - "bingKey": { - "type": "string" - }, - "mapUrl": { - "type": "string" - }, - "poiLayer": { - "type": "string" - }, - "latitude": { - "type": "number" - }, - "longitude": { - "type": "number" - }, - "zoom": { - "type": "integer" - }, - "twelveHourFormat": { - "type": "boolean" - }, - "version": { - "type": "string" - }, - "forceSettings": { - "type": "boolean" - }, - "coordinateFormat": { - "type": "string" - }, - "openIdEnabled": { - "type": "boolean" - }, - "openIdForce": { - "type": "boolean" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Command": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "deviceId": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "type": { - "type": "string" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Device": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "uniqueId": { - "type": "string" - }, - "status": { - "type": "string" - }, - "disabled": { - "type": "boolean" - }, - "lastUpdate": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "positionId": { - "type": "integer" - }, - "groupId": { - "type": "integer" - }, - "phone": { - "type": "string" - }, - "model": { - "type": "string" - }, - "contact": { - "type": "string" - }, - "category": { - "type": "string" - }, - "geofenceIds": { - "type": "array", - "items": { - "type": "integer" - } - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Group": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "groupId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Permission": { - "type": "object", - "properties": { - "userId": { - "type": "integer", - "description": "User Id, can be only first parameter" - }, - "deviceId": { - "type": "integer", - "description": "Device Id, can be first parameter or second only in combination with userId" - }, - "groupId": { - "type": "integer", - "description": "Group Id, can be first parameter or second only in combination with userId" - }, - "geofenceId": { - "type": "integer", - "description": "Geofence Id, can be second parameter only" - }, - "notificationId": { - "type": "integer", - "description": "Notification Id, can be second parameter only" - }, - "calendarId": { - "type": "integer", - "description": "Calendar Id, can be second parameter only and only in combination with userId" - }, - "attributeId": { - "type": "integer", - "description": "Computed Attribute Id, can be second parameter only" - }, - "driverId": { - "type": "integer", - "description": "Driver Id, can be second parameter only" - }, - "managedUserId": { - "type": "integer", - "description": "User Id, can be second parameter only and only in combination with userId" - } - }, - "description": "This is a permission map that contain two object indexes. It is used to link/unlink objects. Order is important. Example: { deviceId:8, geofenceId: 16 }" - }, - "CommandType": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - } - }, - "Geofence": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "area": { - "type": "string" - }, - "calendarId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Notification": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "type": "string" - }, - "always": { - "type": "boolean" - }, - "web": { - "type": "boolean" - }, - "mail": { - "type": "boolean" - }, - "sms": { - "type": "boolean" - }, - "calendarId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "NotificationType": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - } - }, - "Event": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "type": "string" - }, - "eventTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "deviceId": { - "type": "integer" - }, - "positionId": { - "type": "integer" - }, - "geofenceId": { - "type": "integer" - }, - "maintenanceId": { - "type": "integer" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "ReportSummary": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "deviceName": { - "type": "string" - }, - "maxSpeed": { - "type": "number", - "description": "in knots" - }, - "averageSpeed": { - "type": "number", - "description": "in knots" - }, - "distance": { - "type": "number", - "description": "in meters" - }, - "spentFuel": { - "type": "number", - "description": "in liters" - }, - "engineHours": { - "type": "integer" - } - } - }, - "ReportTrips": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "deviceName": { - "type": "string" - }, - "maxSpeed": { - "type": "number", - "description": "in knots" - }, - "averageSpeed": { - "type": "number", - "description": "in knots" - }, - "distance": { - "type": "number", - "description": "in meters" - }, - "spentFuel": { - "type": "number", - "description": "in liters" - }, - "duration": { - "type": "integer" - }, - "startTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "startAddress": { - "type": "string" - }, - "startLat": { - "type": "number" - }, - "startLon": { - "type": "number" - }, - "endTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "endAddress": { - "type": "string" - }, - "endLat": { - "type": "number" - }, - "endLon": { - "type": "number" - }, - "driverUniqueId": { - "type": "integer" - }, - "driverName": { - "type": "string" - } - } - }, - "ReportStops": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "deviceName": { - "type": "string" - }, - "duration": { - "type": "integer" - }, - "startTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "address": { - "type": "string" - }, - "lat": { - "type": "number" - }, - "lon": { - "type": "number" - }, - "endTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "spentFuel": { - "type": "number", - "description": "in liters" - }, - "engineHours": { - "type": "integer" - } - } - }, - "Statistics": { - "type": "object", - "properties": { - "captureTime": { - "type": "string", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "format": "date-time" - }, - "activeUsers": { - "type": "integer" - }, - "activeDevices": { - "type": "integer" - }, - "requests": { - "type": "integer" - }, - "messagesReceived": { - "type": "integer" - }, - "messagesStored": { - "type": "integer" - } - } - }, - "DeviceAccumulators": { - "type": "object", - "properties": { - "deviceId": { - "type": "integer" - }, - "totalDistance": { - "type": "number", - "description": "in meters" - }, - "hours": { - "type": "number" - } - } - }, - "Calendar": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "data": { - "type": "string", - "description": "base64 encoded in iCalendar format" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Attribute": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "attribute": { - "type": "string" - }, - "expression": { - "type": "string" - }, - "type": { - "type": "string", - "description": "String|Number|Boolean" - } - } - }, - "Driver": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "uniqueId": { - "type": "string" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - }, - "Maintenance": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - }, - "start": { - "type": "number" - }, - "period": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - }, - "parameters": { - "entityId": { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - }, - "all": { - "name": "all", - "in": "query", - "description": "Can only be used by admins or managers to fetch all entities", - "schema": { - "type": "boolean" - } - }, - "refresh": { - "name": "refresh", - "in": "query", - "schema": { - "type": "boolean" - } - }, - "userId": { - "name": "userId", - "in": "query", - "description": "Standard users can use this only with their own _userId_", - "schema": { - "type": "integer" - } - }, - "deviceId": { - "name": "deviceId", - "in": "query", - "description": "Standard users can use this only with _deviceId_s, they have access to", - "schema": { - "type": "integer" - } - }, - "groupId": { - "name": "groupId", - "in": "query", - "description": "Standard users can use this only with _groupId_s, they have access to", - "schema": { - "type": "integer" - } - }, - "deviceIdArray": { - "name": "deviceId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - "groupIdArray": { - "name": "groupId", - "in": "query", - "style": "form", - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - }, - "fromTime": { - "name": "from", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - }, - "toTime": { - "name": "to", - "in": "query", - "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - } - } - }, - "requestBodies": { - "Device": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, - "Permission": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Permission" - } - } - }, - "required": true - }, - "Group": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Group" - } - } - }, - "required": true - }, - "User": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - }, - "required": true - }, - "Geofence": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Geofence" - } - } - }, - "required": true - }, - "Calendar": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Calendar" - } - } - }, - "required": true - }, - "Attribute": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Attribute" - } - } - }, - "required": true - }, - "Driver": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Driver" - } - } - }, - "required": true - }, - "Command": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Command" - } - } - }, - "required": true - }, - "Notification": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notification" - } - } - }, - "required": true - }, - "Maintenance": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Maintenance" - } - } - }, - "required": true - } - }, - "securitySchemes": { - "basicAuth": { - "type": "http", - "description": "Basic HTTP authorization with _email_ and _password_", - "scheme": "basic" - } - } - } -} +{ + "openapi": "3.0.1", + "info": { + "title": "Traccar", + "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", + "url": "https://www.traccar.org/", + "email": "support@traccar.org" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "servers": [ + { + "url": "https://demo.traccar.org/api", + "description": "Demo Server 1" + }, + { + "url": "https://demo2.traccar.org/api", + "description": "Demo Server 2" + }, + { + "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" + }, + { + "url": "http://{host}:{port}/api", + "description": "Other Server", + "variables": { + "host": { + "default": "localhost" + }, + "port": { + "enum": [ + "8082", + "80" + ], + "default": "8082" + } + } + } + ], + "security": [ + { + "basicAuth": [] + } + ], + "tags": [ + { + "name": "Server", + "description": "Server information" + }, + { + "name": "Session", + "description": "User session management" + }, + { + "name": "Devices", + "description": "Device management" + }, + { + "name": "Groups", + "description": "Group management" + }, + { + "name": "Users", + "description": "User management" + }, + { + "name": "Permissions", + "description": "User permissions and other object linking" + }, + { + "name": "Positions", + "description": "Retrieving raw location information" + }, + { + "name": "Events", + "description": "Retrieving event information" + }, + { + "name": "Reports", + "description": "Reports generation" + }, + { + "name": "Notifications", + "description": "User notifications management" + }, + { + "name": "Geofences", + "description": "Geofence management" + }, + { + "name": "Commands", + "description": "Sending commands to devices and stored command management" + }, + { + "name": "Attributes", + "description": "Computed attributes management" + }, + { + "name": "Drivers", + "description": "Drivers management" + }, + { + "name": "Maintenance", + "description": "Maintenance management" + }, + { + "name": "Calendars", + "description": "Calendar management" + }, + { + "name": "Statistics", + "description": "Retrieving server statistics" + } + ], + "paths": { + "/commands": { + "get": { + "summary": "Fetch a list of Saved Commands", + "tags": [ + "Commands" + ], + "description": "Without params, it returns a list of Saved Commands the user has access to", + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Saved Command", + "tags": [ + "Commands" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/commands/{id}": { + "put": { + "summary": "Update a Saved Command", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Saved Command", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/commands/send": { + "get": { + "summary": "Fetch a list of Saved Commands supported by Device at the moment", + "description": "Return a list of saved commands linked to Device and its groups, filtered by current Device protocol support", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Command" + } + } + } + } + }, + "400": { + "description": "Could happen when the user doesn't have permission for the device", + "content": {} + } + } + }, + "post": { + "summary": "Dispatch commands to device", + "description": "Dispatch a new command or Saved Command if _body.id_ set", + "tags": [ + "Commands" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Command sent", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "202": { + "description": "Command queued", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "400": { + "description": "Could happen when the user doesn't have permission or an incorrect command _type_ for the device", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/commands/types": { + "get": { + "summary": "Fetch a list of available Commands for the Device or all possible Commands if Device ommited", + "tags": [ + "Commands" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "description": "Internal device identifier. Only works if device has already reported some locations", + "schema": { + "type": "integer" + } + }, + { + "name": "protocol", + "in": "query", + "description": "Protocol name. Can be used instead of device id", + "schema": { + "type": "string" + } + }, + { + "name": "textChannel", + "in": "query", + "description": "When `true` return SMS commands. If not specified or `false` return data commands", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommandType" + } + } + } + } + }, + "400": { + "description": "Could happen when trying to fetch from a device the user does not have permission", + "content": {} + } + } + } + }, + "/devices": { + "get": { + "summary": "Fetch a list of Devices", + "description": "Without any params, returns a list of the user's devices", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "id", + "in": "query", + "description": "To fetch one or more devices. Multiple params can be passed like `id=31&id=42`", + "schema": { + "type": "integer" + } + }, + { + "name": "uniqueId", + "in": "query", + "description": "To fetch one or more devices. Multiple params can be passed like `uniqueId=333331&uniqieId=44442`", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Device" + } + } + } + } + }, + "400": { + "description": "No permission", + "content": {} + } + } + }, + "post": { + "summary": "Create a Device", + "tags": [ + "Devices" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/devices/{id}": { + "put": { + "summary": "Update a Device", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Device", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/devices/{id}/accumulators": { + "put": { + "summary": "Update total distance and hours of the Device", + "tags": [ + "Devices" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceAccumulators" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/groups": { + "get": { + "summary": "Fetch a list of Groups", + "description": "Without any params, returns a list of the Groups the user belongs to", + "tags": [ + "Groups" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Group" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Group", + "tags": [ + "Groups" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + } + }, + "400": { + "description": "No permission", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/groups/{id}": { + "put": { + "summary": "Update a Group", + "tags": [ + "Groups" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Group", + "tags": [ + "Groups" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/permissions": { + "post": { + "summary": "Link an Object to another Object", + "tags": [ + "Permissions" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Permission" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content", + "content": {} + }, + "400": { + "description": "No permission", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Unlink an Object from another Object", + "tags": [ + "Permissions" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Permission" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content", + "content": {} + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/positions": { + "get": { + "summary": "Fetches a list of Positions", + "description": "We strongly recommend using [Traccar WebSocket API](https://www.traccar.org/traccar-api/) instead of periodically polling positions endpoint. Without any params, it returns a list of last known positions for all the user's Devices. _from_ and _to_ fields are not required with _id_.", + "tags": [ + "Positions" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "description": "_deviceId_ is optional, but requires the _from_ and _to_ parameters when used", + "schema": { + "type": "integer" + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "id", + "in": "query", + "description": "To fetch one or more positions. Multiple params can be passed like `id=31&id=42`", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + }, + "text/csv": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + }, + "application/gpx+xml": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + } + } + } + } + } + }, + "/server": { + "get": { + "summary": "Fetch Server information", + "tags": [ + "Server" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Server" + } + } + } + } + } + }, + "put": { + "summary": "Update Server information", + "tags": [ + "Server" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Server" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Server" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/session": { + "get": { + "summary": "Fetch Session information", + "tags": [ + "Session" + ], + "parameters": [ + { + "name": "token", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "404": { + "description": "Not Found", + "content": {} + } + } + }, + "post": { + "summary": "Create a new Session", + "tags": [ + "Session" + ], + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "required": [ + "email", + "password" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string", + "format": "password" + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + } + } + }, + "delete": { + "summary": "Close the Session", + "tags": [ + "Session" + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/session/openid/auth": { + "get": { + "summary": "Fetch Session information", + "tags": [ + "Session" + ], + "parameters": [ + { + } + ], + "responses": { + "303": { + "description": "Redirect to OpenID Connect identity provider", + "content": { } + } + } + } + }, + "/session/openid/callback": { + "get": { + "summary": "OpenID Callback", + "tags": [ + "Session" + ], + "parameters": [ + { + } + ], + "responses": { + "303": { + "description": "Successful authentication, redirect to homepage", + "content": { } + } + } + } + }, + "/users": { + "get": { + "summary": "Fetch a list of Users", + "tags": [ + "Users" + ], + "parameters": [ + { + "name": "userId", + "in": "query", + "description": "Can only be used by admin or manager users", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "400": { + "description": "No Permission", + "content": {} + } + } + }, + "post": { + "summary": "Create a User", + "tags": [ + "Users" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/users/{id}": { + "put": { + "summary": "Update a User", + "tags": [ + "Users" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a User", + "tags": [ + "Users" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/notifications": { + "get": { + "summary": "Fetch a list of Notifications", + "description": "Without params, it returns a list of Notifications the user has access to", + "tags": [ + "Notifications" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Notification", + "tags": [ + "Notifications" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/notifications/{id}": { + "put": { + "summary": "Update a Notification", + "tags": [ + "Notifications" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Notification", + "tags": [ + "Notifications" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/notifications/types": { + "get": { + "summary": "Fetch a list of available Notification types", + "tags": [ + "Notifications" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationType" + } + } + } + } + } + } + } + }, + "/notifications/test": { + "post": { + "summary": "Send test notification to current user via Email and SMS", + "tags": [ + "Notifications" + ], + "responses": { + "204": { + "description": "Successful sending", + "content": {} + }, + "400": { + "description": "Could happen if sending has failed", + "content": {} + } + } + } + }, + "/geofences": { + "get": { + "summary": "Fetch a list of Geofences", + "description": "Without params, it returns a list of Geofences the user has access to", + "tags": [ + "Geofences" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Geofence" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Geofence", + "tags": [ + "Geofences" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/geofences/{id}": { + "put": { + "summary": "Update a Geofence", + "tags": [ + "Geofences" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Geofence", + "tags": [ + "Geofences" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/events/{id}": { + "get": { + "tags": [ + "Events" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + } + } + } + } + } + } + }, + "/reports/route": { + "get": { + "summary": "Fetch a list of Positions within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Position" + } + } + } + } + } + } + } + }, + "/reports/events": { + "get": { + "summary": "Fetch a list of Events within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "type", + "in": "query", + "description": "% can be used to return events of all types", + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Event" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Event" + } + } + } + } + } + } + } + }, + "/reports/summary": { + "get": { + "summary": "Fetch a list of ReportSummary within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportSummary" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportSummary" + } + } + } + } + } + } + } + }, + "/reports/trips": { + "get": { + "summary": "Fetch a list of ReportTrips within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportTrips" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportTrips" + } + } + } + } + } + } + } + }, + "/reports/stops": { + "get": { + "summary": "Fetch a list of ReportStops within the time period for the Devices or Groups", + "description": "At least one _deviceId_ or one _groupId_ must be passed", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportStops" + } + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportStops" + } + } + } + } + } + } + } + }, + "/statistics": { + "get": { + "summary": "Fetch server Statistics", + "tags": [ + "Statistics" + ], + "parameters": [ + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Statistics" + } + } + } + } + } + } + } + }, + "/calendars": { + "get": { + "summary": "Fetch a list of Calendars", + "description": "Without params, it returns a list of Calendars the user has access to", + "tags": [ + "Calendars" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Calendar" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Calendar", + "tags": [ + "Calendars" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/calendars/{id}": { + "put": { + "summary": "Update a Calendar", + "tags": [ + "Calendars" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Calendar", + "tags": [ + "Calendars" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/attributes/computed": { + "get": { + "summary": "Fetch a list of Attributes", + "description": "Without params, it returns a list of Attributes the user has access to", + "tags": [ + "Attributes" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Attribute" + } + } + } + } + } + } + }, + "post": { + "summary": "Create an Attribute", + "tags": [ + "Attributes" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/attributes/computed/{id}": { + "put": { + "summary": "Update an Attribute", + "tags": [ + "Attributes" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete an Attribute", + "tags": [ + "Attributes" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/drivers": { + "get": { + "summary": "Fetch a list of Drivers", + "description": "Without params, it returns a list of Drivers the user has access to", + "tags": [ + "Drivers" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Driver" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Driver", + "tags": [ + "Drivers" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/drivers/{id}": { + "put": { + "summary": "Update a Driver", + "tags": [ + "Drivers" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Driver", + "tags": [ + "Drivers" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + }, + "/maintenance": { + "get": { + "summary": "Fetch a list of Maintenance", + "description": "Without params, it returns a list of Maintenance the user has access to", + "tags": [ + "Maintenance" + ], + "parameters": [ + { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Maintenance" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a Maintenance", + "tags": [ + "Maintenance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + } + }, + "/maintenance/{id}": { + "put": { + "summary": "Update a Maintenance", + "tags": [ + "Maintenance" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "delete": { + "summary": "Delete a Maintenance", + "tags": [ + "Maintenance" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + } + } + } + } + }, + "components": { + "schemas": { + "Position": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "deviceId": { + "type": "integer" + }, + "protocol": { + "type": "string" + }, + "deviceTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "fixTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "serverTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "outdated": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + }, + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + }, + "altitude": { + "type": "number" + }, + "speed": { + "type": "number", + "description": "in knots" + }, + "course": { + "type": "number" + }, + "address": { + "type": "string" + }, + "accuracy": { + "type": "number" + }, + "network": { + "type": "object", + "properties": {} + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "User": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "readonly": { + "type": "boolean" + }, + "administrator": { + "type": "boolean" + }, + "map": { + "type": "string" + }, + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + }, + "zoom": { + "type": "integer" + }, + "password": { + "type": "string" + }, + "twelveHourFormat": { + "type": "boolean" + }, + "coordinateFormat": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "expirationTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "deviceLimit": { + "type": "integer" + }, + "userLimit": { + "type": "integer" + }, + "deviceReadonly": { + "type": "boolean" + }, + "limitCommands": { + "type": "boolean" + }, + "poiLayer": { + "type": "string" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Server": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "registration": { + "type": "boolean" + }, + "readonly": { + "type": "boolean" + }, + "deviceReadonly": { + "type": "boolean" + }, + "limitCommands": { + "type": "boolean" + }, + "map": { + "type": "string" + }, + "bingKey": { + "type": "string" + }, + "mapUrl": { + "type": "string" + }, + "poiLayer": { + "type": "string" + }, + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + }, + "zoom": { + "type": "integer" + }, + "twelveHourFormat": { + "type": "boolean" + }, + "version": { + "type": "string" + }, + "forceSettings": { + "type": "boolean" + }, + "coordinateFormat": { + "type": "string" + }, + "openIdEnabled": { + "type": "boolean" + }, + "openIdForce": { + "type": "boolean" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Command": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "deviceId": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Device": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "uniqueId": { + "type": "string" + }, + "status": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "lastUpdate": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "positionId": { + "type": "integer" + }, + "groupId": { + "type": "integer" + }, + "phone": { + "type": "string" + }, + "model": { + "type": "string" + }, + "contact": { + "type": "string" + }, + "category": { + "type": "string" + }, + "geofenceIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Group": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Permission": { + "type": "object", + "properties": { + "userId": { + "type": "integer", + "description": "User Id, can be only first parameter" + }, + "deviceId": { + "type": "integer", + "description": "Device Id, can be first parameter or second only in combination with userId" + }, + "groupId": { + "type": "integer", + "description": "Group Id, can be first parameter or second only in combination with userId" + }, + "geofenceId": { + "type": "integer", + "description": "Geofence Id, can be second parameter only" + }, + "notificationId": { + "type": "integer", + "description": "Notification Id, can be second parameter only" + }, + "calendarId": { + "type": "integer", + "description": "Calendar Id, can be second parameter only and only in combination with userId" + }, + "attributeId": { + "type": "integer", + "description": "Computed Attribute Id, can be second parameter only" + }, + "driverId": { + "type": "integer", + "description": "Driver Id, can be second parameter only" + }, + "managedUserId": { + "type": "integer", + "description": "User Id, can be second parameter only and only in combination with userId" + } + }, + "description": "This is a permission map that contain two object indexes. It is used to link/unlink objects. Order is important. Example: { deviceId:8, geofenceId: 16 }" + }, + "CommandType": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + }, + "Geofence": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "area": { + "type": "string" + }, + "calendarId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Notification": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "always": { + "type": "boolean" + }, + "web": { + "type": "boolean" + }, + "mail": { + "type": "boolean" + }, + "sms": { + "type": "boolean" + }, + "calendarId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "NotificationType": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + }, + "Event": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "eventTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "deviceId": { + "type": "integer" + }, + "positionId": { + "type": "integer" + }, + "geofenceId": { + "type": "integer" + }, + "maintenanceId": { + "type": "integer" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "ReportSummary": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "deviceName": { + "type": "string" + }, + "maxSpeed": { + "type": "number", + "description": "in knots" + }, + "averageSpeed": { + "type": "number", + "description": "in knots" + }, + "distance": { + "type": "number", + "description": "in meters" + }, + "spentFuel": { + "type": "number", + "description": "in liters" + }, + "engineHours": { + "type": "integer" + } + } + }, + "ReportTrips": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "deviceName": { + "type": "string" + }, + "maxSpeed": { + "type": "number", + "description": "in knots" + }, + "averageSpeed": { + "type": "number", + "description": "in knots" + }, + "distance": { + "type": "number", + "description": "in meters" + }, + "spentFuel": { + "type": "number", + "description": "in liters" + }, + "duration": { + "type": "integer" + }, + "startTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "startAddress": { + "type": "string" + }, + "startLat": { + "type": "number" + }, + "startLon": { + "type": "number" + }, + "endTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "endAddress": { + "type": "string" + }, + "endLat": { + "type": "number" + }, + "endLon": { + "type": "number" + }, + "driverUniqueId": { + "type": "integer" + }, + "driverName": { + "type": "string" + } + } + }, + "ReportStops": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "deviceName": { + "type": "string" + }, + "duration": { + "type": "integer" + }, + "startTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "address": { + "type": "string" + }, + "lat": { + "type": "number" + }, + "lon": { + "type": "number" + }, + "endTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "spentFuel": { + "type": "number", + "description": "in liters" + }, + "engineHours": { + "type": "integer" + } + } + }, + "Statistics": { + "type": "object", + "properties": { + "captureTime": { + "type": "string", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "format": "date-time" + }, + "activeUsers": { + "type": "integer" + }, + "activeDevices": { + "type": "integer" + }, + "requests": { + "type": "integer" + }, + "messagesReceived": { + "type": "integer" + }, + "messagesStored": { + "type": "integer" + } + } + }, + "DeviceAccumulators": { + "type": "object", + "properties": { + "deviceId": { + "type": "integer" + }, + "totalDistance": { + "type": "number", + "description": "in meters" + }, + "hours": { + "type": "number" + } + } + }, + "Calendar": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "data": { + "type": "string", + "description": "base64 encoded in iCalendar format" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Attribute": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "attribute": { + "type": "string" + }, + "expression": { + "type": "string" + }, + "type": { + "type": "string", + "description": "String|Number|Boolean" + } + } + }, + "Driver": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "uniqueId": { + "type": "string" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + }, + "Maintenance": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "start": { + "type": "number" + }, + "period": { + "type": "number" + }, + "attributes": { + "type": "object", + "properties": {} + } + } + } + }, + "parameters": { + "entityId": { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + }, + "all": { + "name": "all", + "in": "query", + "description": "Can only be used by admins or managers to fetch all entities", + "schema": { + "type": "boolean" + } + }, + "refresh": { + "name": "refresh", + "in": "query", + "schema": { + "type": "boolean" + } + }, + "userId": { + "name": "userId", + "in": "query", + "description": "Standard users can use this only with their own _userId_", + "schema": { + "type": "integer" + } + }, + "deviceId": { + "name": "deviceId", + "in": "query", + "description": "Standard users can use this only with _deviceId_s, they have access to", + "schema": { + "type": "integer" + } + }, + "groupId": { + "name": "groupId", + "in": "query", + "description": "Standard users can use this only with _groupId_s, they have access to", + "schema": { + "type": "integer" + } + }, + "deviceIdArray": { + "name": "deviceId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "groupIdArray": { + "name": "groupId", + "in": "query", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "fromTime": { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + }, + "toTime": { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "required": true, + "schema": { + "type": "string", + "format": "date-time" + } + } + }, + "requestBodies": { + "Device": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "Permission": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Permission" + } + } + }, + "required": true + }, + "Group": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Group" + } + } + }, + "required": true + }, + "User": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + }, + "required": true + }, + "Geofence": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Geofence" + } + } + }, + "required": true + }, + "Calendar": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Calendar" + } + } + }, + "required": true + }, + "Attribute": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Attribute" + } + } + }, + "required": true + }, + "Driver": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Driver" + } + } + }, + "required": true + }, + "Command": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + }, + "required": true + }, + "Notification": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + }, + "required": true + }, + "Maintenance": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Maintenance" + } + } + }, + "required": true + } + }, + "securitySchemes": { + "basicAuth": { + "type": "http", + "description": "Basic HTTP authorization with _email_ and _password_", + "scheme": "basic" + } + } + } +} -- cgit v1.2.3 From 9de791026d5aaf5b5997ed7fab4d30c6cb1fb057 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 17:53:15 +0100 Subject: Lint fixes --- src/main/java/org/traccar/MainModule.java | 2 +- .../org/traccar/api/resource/ServerResource.java | 2 +- .../org/traccar/api/resource/SessionResource.java | 2 +- .../org/traccar/api/resource/UserResource.java | 1 - .../org/traccar/api/security/LoginService.java | 2 +- src/main/java/org/traccar/config/Keys.java | 2 +- .../java/org/traccar/database/OpenIdProvider.java | 73 ++++++++++++---------- 7 files changed, 46 insertions(+), 38 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 7b06b4840..51097511a 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -171,7 +171,7 @@ public class MainModule extends AbstractModule { } return null; } - + @Singleton @Provides public static OpenIdProvider provideOpenIDProvider(Config config, LoginService loginService) { diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 9b4d82a66..6a3b8919e 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -71,7 +71,7 @@ public class ServerResource extends BaseResource { server.setEmailEnabled(mailManager.getEmailEnabled()); server.setGeocoderEnabled(geocoder != null); server.setOpenIdEnabled(openIdProvider != null); - server.setOpenIdForce(openIdProvider != null && openIdProvider.force); + server.setOpenIdForce(openIdProvider != null && openIdProvider.getForce()); User user = permissionsService.getUser(getUserId()); if (user != null) { if (user.getAdministrator()) { diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 94a6a4595..ac39fa449 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -174,7 +174,7 @@ public class SessionResource extends BaseResource { public Response openIdAuth() throws IOException { return Response.seeOther(openIdProvider.createAuthUri()).build(); } - + @PermitAll @Path("openid/callback") @GET diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 1c58cec3c..19d88782f 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -17,7 +17,6 @@ package org.traccar.api.resource; import org.traccar.api.BaseObjectResource; import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.helper.LogAction; import org.traccar.helper.model.UserUtil; import org.traccar.model.ManagedUser; diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index d92f7ce15..c7482a2e3 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -107,7 +107,7 @@ public class LoginService { user.setEmail(email); user.setFixedEmail(true); user.setAdministrator(administrator); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); checkUserEnabled(user); return user; } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index a666667d4..707e9e815 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -628,7 +628,7 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * OpenID Connect Client Secret. + * OpenID Connect Client Secret. * This is a secret assigned to each application you register with your identity provider. * Required to enable SSO. */ diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 5e5c54523..f5c7eef15 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -50,7 +50,6 @@ import com.nimbusds.oauth2.sdk.token.BearerAccessToken; import com.nimbusds.oauth2.sdk.id.State; import com.nimbusds.oauth2.sdk.id.ClientID; import com.nimbusds.openid.connect.sdk.OIDCTokenResponse; -import com.nimbusds.openid.connect.sdk.Nonce; import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; import com.nimbusds.openid.connect.sdk.UserInfoResponse; import com.nimbusds.openid.connect.sdk.UserInfoRequest; @@ -60,8 +59,8 @@ import com.nimbusds.openid.connect.sdk.claims.UserInfo; public class OpenIdProvider { private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); - - public final Boolean force; + + private final Boolean force; private final ClientID clientId; private final ClientAuthentication clientAuth; private URI callbackUrl; @@ -74,7 +73,7 @@ public class OpenIdProvider { private LoginService loginService; @Inject - public OpenIdProvider(Config config, LoginService loginService) { + public OpenIdProvider(Config config, LoginService loginService) { this.loginService = loginService; force = config.getBoolean(Keys.OPENID_FORCE); @@ -87,7 +86,7 @@ public class OpenIdProvider { tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - } catch(URISyntaxException error) { + } catch (URISyntaxException error) { LOGGER.error("Invalid URIs provided in OpenID configuration"); } @@ -100,24 +99,25 @@ public class OpenIdProvider { new Scope("openid", "profile", "email", "groups"), clientId, callbackUrl); - + return request.endpointURI(authUrl) .state(new State()) .build() .toURI(); } - private OIDCTokenResponse getToken(AuthorizationCode code) throws IOException, ParseException, GeneralSecurityException { - AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); - TokenRequest tokenRequest = new TokenRequest(tokenUrl, clientAuth, codeGrant); + private OIDCTokenResponse getToken( + AuthorizationCode code) throws IOException, ParseException, GeneralSecurityException { + AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callbackUrl); + TokenRequest tokenRequest = new TokenRequest(tokenUrl, clientAuth, codeGrant); - HTTPResponse tokenResponse = tokenRequest.toHTTPRequest().send(); - TokenResponse token = OIDCTokenResponseParser.parse(tokenResponse); - if (!token.indicatesSuccess()) { - throw new GeneralSecurityException("Unable to authenticate with the OpenID Connect provider."); - } + HTTPResponse tokenResponse = tokenRequest.toHTTPRequest().send(); + TokenResponse token = OIDCTokenResponseParser.parse(tokenResponse); + if (!token.indicatesSuccess()) { + throw new GeneralSecurityException("Unable to authenticate with the OpenID Connect provider."); + } - return (OIDCTokenResponse) token.toSuccessResponse(); + return (OIDCTokenResponse) token.toSuccessResponse(); } private UserInfo getUserInfo(BearerAccessToken token) throws IOException, ParseException, GeneralSecurityException { @@ -128,36 +128,45 @@ public class OpenIdProvider { UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse); if (!userInfoResponse.indicatesSuccess()) { - throw new GeneralSecurityException("Failed to access OpenID Connect user info endpoint. Please contact your administrator."); + throw new GeneralSecurityException( + "Failed to access OpenID Connect user info endpoint. Please contact your administrator."); } return userInfoResponse.toSuccessResponse().getUserInfo(); } - public URI handleCallback(URI requestUri, HttpServletRequest request) throws StorageException, ParseException, IOException, GeneralSecurityException { - AuthorizationResponse response = AuthorizationResponse.parse(requestUri); + public URI handleCallback( + URI requestUri, HttpServletRequest request + ) throws StorageException, ParseException, IOException, GeneralSecurityException { + AuthorizationResponse response = AuthorizationResponse.parse(requestUri); - if (!response.indicatesSuccess()) { - throw new GeneralSecurityException(response.toErrorResponse().getErrorObject().getDescription()); - } + if (!response.indicatesSuccess()) { + throw new GeneralSecurityException(response.toErrorResponse().getErrorObject().getDescription()); + } - AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); + AuthorizationCode authCode = response.toSuccessResponse().getAuthorizationCode(); - if (authCode == null) { - throw new GeneralSecurityException( "Malformed OpenID callback."); - } + if (authCode == null) { + throw new GeneralSecurityException("Malformed OpenID callback."); + } + + OIDCTokenResponse tokens = getToken(authCode); - OIDCTokenResponse tokens = getToken(authCode); + BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); - BearerAccessToken bearerToken = tokens.getOIDCTokens().getBearerAccessToken(); + UserInfo userInfo = getUserInfo(bearerToken); - UserInfo userInfo = getUserInfo(bearerToken); + User user = loginService.login( + userInfo.getEmailAddress(), userInfo.getName(), + userInfo.getStringListClaim("groups").contains(adminGroup)); - User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), userInfo.getStringListClaim("groups").contains(adminGroup)); + request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); - request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return baseUrl; + } - return baseUrl; + public boolean getForce() { + return force; } } -- cgit v1.2.3 From a16da3bef30b26cbf813526dee817538b99d9d6e Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 21:30:28 +0100 Subject: Support providers who do not provide the groups scope --- src/main/java/org/traccar/config/Keys.java | 6 +++--- src/main/java/org/traccar/database/OpenIdProvider.java | 14 ++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 707e9e815..3ff423ad1 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -665,12 +665,12 @@ public final class Keys { /** * OpenID Connect group to grant admin access. - * Defaults to admins. + * If this is not provided, no groups will be granted admin access. + * This option will only work if your OpenID provider supports the groups scope. */ public static final ConfigKey OPENID_ADMINGROUP = new StringConfigKey( "openid.adminGroup", - List.of(KeyType.CONFIG), - "admins"); + List.of(KeyType.CONFIG)); /** * If no data is reported by a device for the given amount of time, status changes from online to unknown. Value is diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index f5c7eef15..537319b31 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -94,9 +94,15 @@ public class OpenIdProvider { } public URI createAuthUri() { + Scope scope = new Scope("openid", "profile", "email"); + + if (adminGroup != null) { + scope.add("groups"); + } + AuthenticationRequest.Builder request = new AuthenticationRequest.Builder( new ResponseType("code"), - new Scope("openid", "profile", "email", "groups"), + scope, clientId, callbackUrl); @@ -156,9 +162,9 @@ public class OpenIdProvider { UserInfo userInfo = getUserInfo(bearerToken); - User user = loginService.login( - userInfo.getEmailAddress(), userInfo.getName(), - userInfo.getStringListClaim("groups").contains(adminGroup)); + Boolean administrator = adminGroup != null && userInfo.getStringListClaim("groups").contains(adminGroup); + + User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), administrator); request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); -- cgit v1.2.3 From cf992ec194ef8fbcd86ad170bdc68c6075712591 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2023 22:22:20 +0100 Subject: Block login when openid is forced --- src/main/java/org/traccar/api/security/LoginService.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index c7482a2e3..db9ed6cff 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -43,6 +43,7 @@ public class LoginService { private final String serviceAccountToken; private final boolean forceLdap; + private final boolean forceOpenId; @Inject public LoginService( @@ -53,6 +54,7 @@ public class LoginService { this.ldapProvider = ldapProvider; serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); forceLdap = config.getBoolean(Keys.LDAP_FORCE); + forceOpenId = config.getBoolean(Keys.OPENID_FORCE); } public User login(String token) throws StorageException, GeneralSecurityException, IOException { @@ -69,6 +71,10 @@ public class LoginService { } public User login(String email, String password) throws StorageException { + if (forceOpenId) { + return null; + } + email = email.trim(); User user = storage.getObject(User.class, new Request( new Columns.All(), -- cgit v1.2.3 From 77e98161d8742548ef4082054304bad21f7324ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Apr 2023 11:02:05 -0700 Subject: Handle FMB920 LTE cell info --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 929eca8aa..ead657893 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -253,7 +253,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(182, null, (p, b) -> p.set(Position.KEY_HDOP, b.readUnsignedShort() * 0.1)); register(199, null, (p, b) -> p.set(Position.KEY_ODOMETER_TRIP, b.readUnsignedInt())); register(200, fmbXXX, (p, b) -> p.set("sleepMode", b.readUnsignedByte())); - register(205, fmbXXX, (p, b) -> p.set("cid", b.readUnsignedShort())); + register(205, fmbXXX, (p, b) -> p.set("cid2g", b.readUnsignedShort())); register(206, fmbXXX, (p, b) -> p.set("lac", b.readUnsignedShort())); register(236, null, (p, b) -> { p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); @@ -276,6 +276,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { break; } }); + register(636, fmbXXX, (p, b) -> p.set("cid4g", b.readUnsignedInt())); } private void decodeGh3000Parameter(Position position, int id, ByteBuf buf, int length) { @@ -366,10 +367,18 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(network); } } else { - Integer cid = (Integer) position.getAttributes().remove("cid"); + Integer cid2g = (Integer) position.getAttributes().remove("cid2g"); + Long cid4g = (Long) position.getAttributes().remove("cid4g"); Integer lac = (Integer) position.getAttributes().remove("lac"); - if (cid != null && lac != null) { - CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); + if (lac != null && (cid2g != null || cid4g != null)) { + CellTower cellTower; + if (cid2g != null) { + cellTower = CellTower.fromLacCid(getConfig(), lac, cid2g); + cellTower.setRadioType("gsm"); + } else { + cellTower = CellTower.fromLacCid(getConfig(), lac, cid4g); + cellTower.setRadioType("lte"); + } long operator = position.getInteger(Position.KEY_OPERATOR); if (operator >= 1000) { cellTower.setOperator(operator); -- cgit v1.2.3 From 9423dad9bc56674dd864897c9c0265ca8cea6670 Mon Sep 17 00:00:00 2001 From: Roberto Murguia Date: Tue, 4 Apr 2023 17:14:29 -0500 Subject: Add DELETE api endpoint for Positions --- .../org/traccar/api/resource/PositionResource.java | 17 ++++++++ swagger.json | 48 ++++++++++++++++++++++ 2 files changed, 65 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 042dd1e23..37696a620 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -31,6 +31,7 @@ import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.DELETE; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; @@ -43,6 +44,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.LinkedList; @Path("positions") @Produces(MediaType.APPLICATION_JSON) @@ -86,6 +88,21 @@ public class PositionResource extends BaseResource { } } + @DELETE + public Response remove( + @QueryParam("deviceId") long deviceId, + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); + + var conditions = new LinkedList(); + conditions.add(new Condition.Equals("deviceId", deviceId)); + conditions.add(new Condition.Between("fixTime", "from", from, "to", to)); + storage.removeObject(Position.class, new Request(Condition.merge(conditions))); + + return Response.status(Response.Status.NO_CONTENT).build(); + } + @Path("kml") @GET @Produces("application/vnd.google-earth.kml+xml") diff --git a/swagger.json b/swagger.json index 6c1e21d28..467925ca9 100644 --- a/swagger.json +++ b/swagger.json @@ -873,6 +873,54 @@ } } } + }, + "delete": { + "summary": "Deletes all the Positions of a device in the time span specified", + "description": "", + "tags": [ + "Positions" + ], + "parameters": [ + { + "name": "deviceId", + "in": "query", + "description": "", + "schema": { + "type": "integer" + }, + "required": true + }, + { + "name": "from", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "schema": { + "type": "string", + "format": "date-time" + }, + "required": true + }, + { + "name": "to", + "in": "query", + "description": "in IS0 8601 format. eg. `1963-11-22T18:30:00Z`", + "schema": { + "type": "string", + "format": "date-time" + }, + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "content": {} + }, + "400": { + "description": "Bad Request", + "content": {} + } + } } }, "/server": { -- cgit v1.2.3 From 9ab4a6e303c0e8a4997252b4c6a8b2dd601d73af Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 17:40:11 +0100 Subject: Implement OpenID auto discovery --- src/main/java/org/traccar/config/Keys.java | 15 ++++++-- .../java/org/traccar/database/OpenIdProvider.java | 44 ++++++++++++++++++++-- 2 files changed, 53 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 3ff423ad1..3ed6c6026 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -636,11 +636,20 @@ public final class Keys { "openid.clientSecret", List.of(KeyType.CONFIG)); + /** + * OpenID Connect Issuer (Base) URL. + * This is used to automatically configure the authorization, token and user info URLs if + * they are not provided. + */ + public static final ConfigKey OPENID_ISSUERURL = new StringConfigKey( + "openid.issuerUrl", + List.of(KeyType.CONFIG)); + /** * OpenID Connect Authorization URL. * This can usually be found in the documentation of your identity provider or by using the well-known * configuration endpoint, eg. https://auth.example.com//.well-known/openid-configuration - * Required to enable SSO. + * Required to enable SSO if openid.issuerUrl is not set. */ public static final ConfigKey OPENID_AUTHURL = new StringConfigKey( "openid.authUrl", @@ -648,7 +657,7 @@ public final class Keys { /** * OpenID Connect Token URL. * This can be found in the same ways at openid.authUrl. - * Required to enable SSO. + * Required to enable SSO if openid.issuerUrl is not set. */ public static final ConfigKey OPENID_TOKENURL = new StringConfigKey( "openid.tokenUrl", @@ -657,7 +666,7 @@ public final class Keys { /** * OpenID Connect User Info URL. * This can be found in the same ways at openid.authUrl. - * Required to enable SSO. + * Required to enable SSO if openid.issuerUrl is not set. */ public static final ConfigKey OPENID_USERINFOURL = new StringConfigKey( "openid.userInfoUrl", diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 537319b31..2b0f9d290 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -26,9 +26,16 @@ import org.traccar.helper.ServletHelper; import java.net.URI; import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse.BodyHandlers; import java.security.GeneralSecurityException; +import java.util.Map; import java.io.IOException; import javax.servlet.http.HttpServletRequest; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,12 +89,43 @@ public class OpenIdProvider { try { callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, "")); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + + if ( + config.hasKey(Keys.OPENID_ISSUERURL) + && ( + !config.hasKey(Keys.OPENID_AUTHURL) + || !config.hasKey(Keys.OPENID_TOKENURL) + || !config.hasKey(Keys.OPENID_USERINFOURL)) + ) { + HttpClient httpClient = HttpClient.newHttpClient(); + + HttpRequest httpRequest = HttpRequest.newBuilder( + URI.create( + config.getString(Keys.OPENID_ISSUERURL) + "/.well-known/openid-configuration") + ) + .header("accept", "application/json") + .build(); + + String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); + + Map discoveryMap = new ObjectMapper().readValue( + httpResponse, new TypeReference>() { }); + + authUrl = new URI(discoveryMap.get("authorization_endpoint").toString()); + tokenUrl = new URI(discoveryMap.get("token_endpoint").toString()); + userInfoUrl = new URI(discoveryMap.get("userinfo_endpoint").toString()); + + LOGGER.info("OpenID Connect auto discovery successful"); + } else { + authUrl = new URI(config.getString(Keys.OPENID_AUTHURL)); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL)); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL)); + } } catch (URISyntaxException error) { LOGGER.error("Invalid URIs provided in OpenID configuration"); + } catch (InterruptedException | IOException error) { + LOGGER.error("OpenID Connect auto discovery failed"); } adminGroup = config.getString(Keys.OPENID_ADMINGROUP); -- cgit v1.2.3 From c56b136a328bc1781ccc74aa27fdecf4a17b9595 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 17:59:04 +0100 Subject: Added openid.allowGroup --- src/main/java/org/traccar/config/Keys.java | 9 +++++++++ src/main/java/org/traccar/database/OpenIdProvider.java | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 3ed6c6026..363d4a472 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -672,6 +672,15 @@ public final class Keys { "openid.userInfoUrl", List.of(KeyType.CONFIG)); + /** + * OpenID Connect group to restrict access to. + * If this is not provided, all OpenID users will have access to Traccar. + * This option will only work if your OpenID provider supports the groups scope. + */ + public static final ConfigKey OPENID_ALLOWGROUP = new StringConfigKey( + "openid.allowGroup", + List.of(KeyType.CONFIG)); + /** * OpenID Connect group to grant admin access. * If this is not provided, no groups will be granted admin access. diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 2b0f9d290..370876ed9 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -30,6 +30,7 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse.BodyHandlers; import java.security.GeneralSecurityException; +import java.util.List; import java.util.Map; import java.io.IOException; import javax.servlet.http.HttpServletRequest; @@ -76,6 +77,7 @@ public class OpenIdProvider { private URI userInfoUrl; private URI baseUrl; private final String adminGroup; + private final String allowGroup; private LoginService loginService; @@ -129,6 +131,7 @@ public class OpenIdProvider { } adminGroup = config.getString(Keys.OPENID_ADMINGROUP); + allowGroup = config.getString(Keys.OPENID_ALLOWGROUP); } public URI createAuthUri() { @@ -200,7 +203,12 @@ public class OpenIdProvider { UserInfo userInfo = getUserInfo(bearerToken); - Boolean administrator = adminGroup != null && userInfo.getStringListClaim("groups").contains(adminGroup); + List userGroups = userInfo.getStringListClaim("groups"); + Boolean administrator = adminGroup != null && userGroups.contains(adminGroup); + + if (!(administrator || allowGroup == null || userGroups.contains(allowGroup))) { + throw new GeneralSecurityException("Your OpenID Groups do not permit access to Traccar."); + } User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), administrator); -- cgit v1.2.3 From 5ba5cc8291d0bd5d497563ddebf08dfc6d239ee9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 20:40:09 +0100 Subject: Review changes --- src/main/java/org/traccar/MainModule.java | 12 +++-- src/main/java/org/traccar/config/Keys.java | 16 +++--- .../java/org/traccar/database/OpenIdProvider.java | 62 +++++++++------------- 3 files changed, 41 insertions(+), 49 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 51097511a..220798767 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -97,6 +97,7 @@ import javax.ws.rs.client.ClientBuilder; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; +import java.net.http.HttpClient; import java.util.Properties; public class MainModule extends AbstractModule { @@ -174,11 +175,12 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static OpenIdProvider provideOpenIDProvider(Config config, LoginService loginService) { - if (config.hasKey(Keys.OPENID_CLIENTID)) { - return new OpenIdProvider(config, loginService); - } - return null; + public static OpenIdProvider provideOpenIDProvider( + Config config, LoginService loginService, ObjectMapper objectMapper) throws InterruptedException, IOException { + if (config.hasKey(Keys.OPENID_CLIENT_ID)) { + return new OpenIdProvider(config, loginService, HttpClient.newHttpClient(), objectMapper); + } + return null; } @Provides diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 363d4a472..6c46ef390 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -623,7 +623,7 @@ public final class Keys { * This is a unique ID assigned to each application you register with your identity provider. * Required to enable SSO. */ - public static final ConfigKey OPENID_CLIENTID = new StringConfigKey( + public static final ConfigKey OPENID_CLIENT_ID = new StringConfigKey( "openid.clientId", List.of(KeyType.CONFIG)); @@ -632,7 +632,7 @@ public final class Keys { * This is a secret assigned to each application you register with your identity provider. * Required to enable SSO. */ - public static final ConfigKey OPENID_CLIENTSECRET = new StringConfigKey( + public static final ConfigKey OPENID_CLIENT_SECRET = new StringConfigKey( "openid.clientSecret", List.of(KeyType.CONFIG)); @@ -641,7 +641,7 @@ public final class Keys { * This is used to automatically configure the authorization, token and user info URLs if * they are not provided. */ - public static final ConfigKey OPENID_ISSUERURL = new StringConfigKey( + public static final ConfigKey OPENID_ISSUER_URL = new StringConfigKey( "openid.issuerUrl", List.of(KeyType.CONFIG)); @@ -651,7 +651,7 @@ public final class Keys { * configuration endpoint, eg. https://auth.example.com//.well-known/openid-configuration * Required to enable SSO if openid.issuerUrl is not set. */ - public static final ConfigKey OPENID_AUTHURL = new StringConfigKey( + public static final ConfigKey OPENID_AUTH_URL = new StringConfigKey( "openid.authUrl", List.of(KeyType.CONFIG)); /** @@ -659,7 +659,7 @@ public final class Keys { * This can be found in the same ways at openid.authUrl. * Required to enable SSO if openid.issuerUrl is not set. */ - public static final ConfigKey OPENID_TOKENURL = new StringConfigKey( + public static final ConfigKey OPENID_TOKEN_URL = new StringConfigKey( "openid.tokenUrl", List.of(KeyType.CONFIG)); @@ -668,7 +668,7 @@ public final class Keys { * This can be found in the same ways at openid.authUrl. * Required to enable SSO if openid.issuerUrl is not set. */ - public static final ConfigKey OPENID_USERINFOURL = new StringConfigKey( + public static final ConfigKey OPENID_USERINFO_URL = new StringConfigKey( "openid.userInfoUrl", List.of(KeyType.CONFIG)); @@ -677,7 +677,7 @@ public final class Keys { * If this is not provided, all OpenID users will have access to Traccar. * This option will only work if your OpenID provider supports the groups scope. */ - public static final ConfigKey OPENID_ALLOWGROUP = new StringConfigKey( + public static final ConfigKey OPENID_ALLOW_GROUP = new StringConfigKey( "openid.allowGroup", List.of(KeyType.CONFIG)); @@ -686,7 +686,7 @@ public final class Keys { * If this is not provided, no groups will be granted admin access. * This option will only work if your OpenID provider supports the groups scope. */ - public static final ConfigKey OPENID_ADMINGROUP = new StringConfigKey( + public static final ConfigKey OPENID_ADMIN_GROUP = new StringConfigKey( "openid.adminGroup", List.of(KeyType.CONFIG)); diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 370876ed9..8b93feea7 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -82,56 +82,46 @@ public class OpenIdProvider { private LoginService loginService; @Inject - public OpenIdProvider(Config config, LoginService loginService) { - this.loginService = loginService; - - force = config.getBoolean(Keys.OPENID_FORCE); - clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); - clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET))); - - try { - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - - if ( - config.hasKey(Keys.OPENID_ISSUERURL) - && ( - !config.hasKey(Keys.OPENID_AUTHURL) - || !config.hasKey(Keys.OPENID_TOKENURL) - || !config.hasKey(Keys.OPENID_USERINFOURL)) - ) { - HttpClient httpClient = HttpClient.newHttpClient(); + public OpenIdProvider( + Config config, LoginService loginService, HttpClient httpClient, ObjectMapper objectMapper + ) throws InterruptedException, IOException { + this.loginService = loginService; + force = config.getBoolean(Keys.OPENID_FORCE); + clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); + clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); + + try { + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { HttpRequest httpRequest = HttpRequest.newBuilder( - URI.create( - config.getString(Keys.OPENID_ISSUERURL) + "/.well-known/openid-configuration") - ) - .header("accept", "application/json") + URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) + .header("Accept", "application/json") .build(); String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); - Map discoveryMap = new ObjectMapper().readValue( + Map discoveryMap = objectMapper.readValue( httpResponse, new TypeReference>() { }); - authUrl = new URI(discoveryMap.get("authorization_endpoint").toString()); - tokenUrl = new URI(discoveryMap.get("token_endpoint").toString()); - userInfoUrl = new URI(discoveryMap.get("userinfo_endpoint").toString()); + authUrl = new URI((String) discoveryMap.get("authorization_endpoint")); + tokenUrl = new URI((String) discoveryMap.get("token_endpoint")); + userInfoUrl = new URI((String) discoveryMap.get("userinfo_endpoint")); LOGGER.info("OpenID Connect auto discovery successful"); - } else { - authUrl = new URI(config.getString(Keys.OPENID_AUTHURL)); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL)); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL)); - } + } else { + authUrl = new URI(config.getString(Keys.OPENID_AUTH_URL)); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKEN_URL)); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFO_URL)); + } } catch (URISyntaxException error) { LOGGER.error("Invalid URIs provided in OpenID configuration"); - } catch (InterruptedException | IOException error) { - LOGGER.error("OpenID Connect auto discovery failed"); } - adminGroup = config.getString(Keys.OPENID_ADMINGROUP); - allowGroup = config.getString(Keys.OPENID_ALLOWGROUP); + adminGroup = config.getString(Keys.OPENID_ADMIN_GROUP); + allowGroup = config.getString(Keys.OPENID_ALLOW_GROUP); } public URI createAuthUri() { -- cgit v1.2.3 From 1ecd7efca41344f29f8caa42fc6caaed8c7294a1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 20:49:10 +0100 Subject: Config doc change --- src/main/java/org/traccar/config/Keys.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6c46ef390..b97acfd66 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -638,8 +638,7 @@ public final class Keys { /** * OpenID Connect Issuer (Base) URL. - * This is used to automatically configure the authorization, token and user info URLs if - * they are not provided. + * This is used to automatically configure the authorization, token and user info URLs if provided. */ public static final ConfigKey OPENID_ISSUER_URL = new StringConfigKey( "openid.issuerUrl", -- cgit v1.2.3 From a710ddd5ad336cd45d3a0e69f13985db840763dc Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 21:45:37 +0100 Subject: Review changes 2 --- src/main/java/org/traccar/MainModule.java | 12 ++-- .../java/org/traccar/database/OpenIdProvider.java | 67 +++++++++------------- 2 files changed, 35 insertions(+), 44 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 220798767..4db6e0e32 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -96,6 +96,7 @@ import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import java.io.IOException; import java.net.InetAddress; +import java.net.URISyntaxException; import java.net.UnknownHostException; import java.net.http.HttpClient; import java.util.Properties; @@ -176,11 +177,12 @@ public class MainModule extends AbstractModule { @Singleton @Provides public static OpenIdProvider provideOpenIDProvider( - Config config, LoginService loginService, ObjectMapper objectMapper) throws InterruptedException, IOException { - if (config.hasKey(Keys.OPENID_CLIENT_ID)) { - return new OpenIdProvider(config, loginService, HttpClient.newHttpClient(), objectMapper); - } - return null; + Config config, LoginService loginService, ObjectMapper objectMapper + ) throws InterruptedException, IOException, URISyntaxException { + if (config.hasKey(Keys.OPENID_CLIENT_ID)) { + return new OpenIdProvider(config, loginService, HttpClient.newHttpClient(), objectMapper); + } + return null; } @Provides diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 8b93feea7..941d0e587 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -38,8 +38,6 @@ import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.nimbusds.oauth2.sdk.http.HTTPResponse; import com.nimbusds.oauth2.sdk.AuthorizationCode; @@ -62,12 +60,9 @@ import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; import com.nimbusds.openid.connect.sdk.UserInfoResponse; import com.nimbusds.openid.connect.sdk.UserInfoRequest; import com.nimbusds.openid.connect.sdk.AuthenticationRequest; - import com.nimbusds.openid.connect.sdk.claims.UserInfo; public class OpenIdProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); - private final Boolean force; private final ClientID clientId; private final ClientAuthentication clientAuth; @@ -84,40 +79,34 @@ public class OpenIdProvider { @Inject public OpenIdProvider( Config config, LoginService loginService, HttpClient httpClient, ObjectMapper objectMapper - ) throws InterruptedException, IOException { - this.loginService = loginService; - - force = config.getBoolean(Keys.OPENID_FORCE); - clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); - clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); - - try { - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - - if (config.hasKey(Keys.OPENID_ISSUER_URL)) { - HttpRequest httpRequest = HttpRequest.newBuilder( - URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) - .header("Accept", "application/json") - .build(); - - String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); - - Map discoveryMap = objectMapper.readValue( - httpResponse, new TypeReference>() { }); - - authUrl = new URI((String) discoveryMap.get("authorization_endpoint")); - tokenUrl = new URI((String) discoveryMap.get("token_endpoint")); - userInfoUrl = new URI((String) discoveryMap.get("userinfo_endpoint")); - - LOGGER.info("OpenID Connect auto discovery successful"); - } else { - authUrl = new URI(config.getString(Keys.OPENID_AUTH_URL)); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKEN_URL)); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFO_URL)); - } - } catch (URISyntaxException error) { - LOGGER.error("Invalid URIs provided in OpenID configuration"); + ) throws InterruptedException, IOException, URISyntaxException { + this.loginService = loginService; + + force = config.getBoolean(Keys.OPENID_FORCE); + clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); + clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); + + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { + HttpRequest httpRequest = HttpRequest.newBuilder( + URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) + .header("Accept", "application/json") + .build(); + + String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); + + Map discoveryMap = objectMapper.readValue( + httpResponse, new TypeReference>() { }); + + authUrl = new URI((String) discoveryMap.get("authorization_endpoint")); + tokenUrl = new URI((String) discoveryMap.get("token_endpoint")); + userInfoUrl = new URI((String) discoveryMap.get("userinfo_endpoint")); + } else { + authUrl = new URI(config.getString(Keys.OPENID_AUTH_URL)); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKEN_URL)); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFO_URL)); } adminGroup = config.getString(Keys.OPENID_ADMIN_GROUP); -- cgit v1.2.3 From c0dd2a6187de517af33aa92e0524414e65d973b4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 22:27:02 +0100 Subject: Rename ServletHelper to WebHelper --- src/main/java/org/traccar/MainModule.java | 15 +------ .../org/traccar/api/resource/SessionResource.java | 14 +++--- .../java/org/traccar/database/OpenIdProvider.java | 6 +-- .../java/org/traccar/helper/ServletHelper.java | 45 ------------------- src/main/java/org/traccar/helper/WebHelper.java | 51 ++++++++++++++++++++++ .../java/org/traccar/helper/ServletHelperTest.java | 39 ----------------- .../java/org/traccar/helper/WebHelperTest.java | 39 +++++++++++++++++ 7 files changed, 102 insertions(+), 107 deletions(-) delete mode 100644 src/main/java/org/traccar/helper/ServletHelper.java create mode 100644 src/main/java/org/traccar/helper/WebHelper.java delete mode 100644 src/test/java/org/traccar/helper/ServletHelperTest.java create mode 100644 src/test/java/org/traccar/helper/WebHelperTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 4db6e0e32..41124bd03 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -75,6 +75,7 @@ import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; import org.traccar.helper.ObjectMapperContextResolver; import org.traccar.helper.SanitizerModule; +import org.traccar.helper.WebHelper; import org.traccar.mail.LogMailManager; import org.traccar.mail.MailManager; import org.traccar.mail.SmtpMailManager; @@ -390,19 +391,7 @@ public class MainModule extends AbstractModule { public static VelocityEngine provideVelocityEngine(Config config) { Properties properties = new Properties(); properties.setProperty("resource.loader.file.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); - - if (config.hasKey(Keys.WEB_URL)) { - properties.setProperty("web.url", config.getString(Keys.WEB_URL).replaceAll("/$", "")); - } else { - String address; - try { - address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; - } - String url = URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); - properties.setProperty("web.url", url); - } + properties.setProperty("web.url", WebHelper.retrieveWebUrl(config)); VelocityEngine velocityEngine = new VelocityEngine(); velocityEngine.init(properties); diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index ac39fa449..9b6a74ddb 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -21,7 +21,7 @@ import org.traccar.api.signature.TokenManager; import org.traccar.database.OpenIdProvider; import org.traccar.helper.DataConverter; import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; +import org.traccar.helper.WebHelper; import org.traccar.model.User; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -84,7 +84,7 @@ public class SessionResource extends BaseResource { User user = loginService.login(token); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } } @@ -111,7 +111,7 @@ public class SessionResource extends BaseResource { User user = loginService.login(email, password); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } } @@ -135,7 +135,7 @@ public class SessionResource extends BaseResource { User user = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", userId))); request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } @@ -146,17 +146,17 @@ public class SessionResource extends BaseResource { User user = loginService.login(email, password); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } else { - LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); + LogAction.failedLogin(WebHelper.retrieveRemoteAddress(request)); throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); } } @DELETE public Response remove() { - LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.logout(getUserId(), WebHelper.retrieveRemoteAddress(request)); request.getSession().removeAttribute(USER_ID_KEY); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 941d0e587..6550a1278 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -22,7 +22,7 @@ import org.traccar.api.security.LoginService; import org.traccar.model.User; import org.traccar.storage.StorageException; import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; +import org.traccar.helper.WebHelper; import java.net.URI; import java.net.URISyntaxException; @@ -88,7 +88,7 @@ public class OpenIdProvider { callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { HttpRequest httpRequest = HttpRequest.newBuilder( URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) @@ -192,7 +192,7 @@ public class OpenIdProvider { User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), administrator); request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return baseUrl; } diff --git a/src/main/java/org/traccar/helper/ServletHelper.java b/src/main/java/org/traccar/helper/ServletHelper.java deleted file mode 100644 index b6c587ec3..000000000 --- a/src/main/java/org/traccar/helper/ServletHelper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 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.helper; - -import javax.servlet.http.HttpServletRequest; - -public final class ServletHelper { - - private ServletHelper() { - } - - public static String retrieveRemoteAddress(HttpServletRequest request) { - - if (request != null) { - String remoteAddress = request.getHeader("X-FORWARDED-FOR"); - - if (remoteAddress != null && !remoteAddress.isEmpty()) { - int separatorIndex = remoteAddress.indexOf(","); - if (separatorIndex > 0) { - return remoteAddress.substring(0, separatorIndex); // remove the additional data - } else { - return remoteAddress; - } - } else { - return request.getRemoteAddr(); - } - } else { - return null; - } - } - -} diff --git a/src/main/java/org/traccar/helper/WebHelper.java b/src/main/java/org/traccar/helper/WebHelper.java new file mode 100644 index 000000000..9c6547d8d --- /dev/null +++ b/src/main/java/org/traccar/helper/WebHelper.java @@ -0,0 +1,51 @@ +/* + * Copyright 2020 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.helper; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import javax.servlet.http.HttpServletRequest; + +import org.eclipse.jetty.util.URIUtil; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +public final class WebHelper { + + private WebHelper() { + } + + public static String retrieveRemoteAddress(HttpServletRequest request) { + + if (request != null) { + String remoteAddress = request.getHeader("X-FORWARDED-FOR"); + + if (remoteAddress != null && !remoteAddress.isEmpty()) { + int separatorIndex = remoteAddress.indexOf(","); + if (separatorIndex > 0) { + return remoteAddress.substring(0, separatorIndex); // remove the additional data + } else { + return remoteAddress; + } + } else { + return request.getRemoteAddr(); + } + } else { + return null; + } + } +} diff --git a/src/test/java/org/traccar/helper/ServletHelperTest.java b/src/test/java/org/traccar/helper/ServletHelperTest.java deleted file mode 100644 index 3a645bc36..000000000 --- a/src/test/java/org/traccar/helper/ServletHelperTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.traccar.helper; - -import org.junit.jupiter.api.Test; - -import javax.servlet.http.HttpServletRequest; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ServletHelperTest { - - @Test - public void testRetrieveRemoteAddressProxyMultiple() { - HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getRemoteAddr()).thenReturn("147.120.1.5"); - when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65, 10.20.10.33, 10.20.20.34"); - - assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); - } - - @Test - public void testRetrieveRemoteAddressProxySingle() { - HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getRemoteAddr()).thenReturn("147.120.1.5"); - when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65"); - - assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); - } - - @Test - public void testRetrieveRemoteAddressNoProxy() { - HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getRemoteAddr()).thenReturn("231.23.45.65"); - - assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); - } - -} diff --git a/src/test/java/org/traccar/helper/WebHelperTest.java b/src/test/java/org/traccar/helper/WebHelperTest.java new file mode 100644 index 000000000..3a7329cb8 --- /dev/null +++ b/src/test/java/org/traccar/helper/WebHelperTest.java @@ -0,0 +1,39 @@ +package org.traccar.helper; + +import org.junit.jupiter.api.Test; + +import javax.servlet.http.HttpServletRequest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class WebHelperTest { + + @Test + public void testRetrieveRemoteAddressProxyMultiple() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("147.120.1.5"); + when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65, 10.20.10.33, 10.20.20.34"); + + assertEquals("231.23.45.65", WebHelper.retrieveRemoteAddress(request)); + } + + @Test + public void testRetrieveRemoteAddressProxySingle() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("147.120.1.5"); + when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65"); + + assertEquals("231.23.45.65", WebHelper.retrieveRemoteAddress(request)); + } + + @Test + public void testRetrieveRemoteAddressNoProxy() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("231.23.45.65"); + + assertEquals("231.23.45.65", WebHelper.retrieveRemoteAddress(request)); + } + +} -- cgit v1.2.3 From 88a56f29fff1ab252a2c415f0d44a22192dd6b66 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 22:29:32 +0100 Subject: Implement retrieveWebUrl --- src/main/java/org/traccar/MainModule.java | 3 --- src/main/java/org/traccar/database/OpenIdProvider.java | 6 +++--- src/main/java/org/traccar/helper/WebHelper.java | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 41124bd03..6a2fe21c3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -26,7 +26,6 @@ import com.google.inject.name.Names; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.apache.velocity.app.VelocityEngine; -import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.broadcast.MulticastBroadcastService; import org.traccar.broadcast.NullBroadcastService; @@ -96,9 +95,7 @@ import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import java.io.IOException; -import java.net.InetAddress; import java.net.URISyntaxException; -import java.net.UnknownHostException; import java.net.http.HttpClient; import java.util.Properties; diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 6550a1278..d0ec4e98d 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -86,9 +86,9 @@ public class OpenIdProvider { clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - + baseUrl = new URI(WebHelper.retrieveWebUrl(config)); + callbackUrl = new URI(WebHelper.retrieveWebUrl(config) + "/api/session/openid/callback"); + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { HttpRequest httpRequest = HttpRequest.newBuilder( URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) diff --git a/src/main/java/org/traccar/helper/WebHelper.java b/src/main/java/org/traccar/helper/WebHelper.java index 9c6547d8d..e2844bc4d 100644 --- a/src/main/java/org/traccar/helper/WebHelper.java +++ b/src/main/java/org/traccar/helper/WebHelper.java @@ -48,4 +48,18 @@ public final class WebHelper { return null; } } + + public static String retrieveWebUrl(Config config) { + if (config.hasKey(Keys.WEB_URL)) { + return config.getString(Keys.WEB_URL).replaceAll("/$", ""); + } else { + String address; + try { + address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + return URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); + } + } } -- cgit v1.2.3 From 4ece72558c80038728fa67ec51238bac48fc4d64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 6 Apr 2023 07:38:08 -0700 Subject: Support GS-404 driver id --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 8 ++++++-- .../java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index ead657893..4968ed05e 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -610,8 +610,12 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { int length = buf.readInt() - 4; getLastLocation(position, new Date(buf.readUnsignedInt() * 1000)); if (isPrintable(buf, length)) { - position.set(Position.KEY_RESULT, - buf.readCharSequence(length, StandardCharsets.US_ASCII).toString().trim()); + String data = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString().trim(); + if (data.startsWith("GTSL")) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, data.split("\\|")[4]); + } else { + position.set(Position.KEY_RESULT, data); + } } else { position.set(Position.KEY_RESULT, ByteBufUtil.hexDump(buf.readSlice(length))); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 60b58f626..0b4f1d243 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -3,6 +3,7 @@ package org.traccar.protocol; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class TeltonikaProtocolDecoderTest extends ProtocolTest { @@ -14,6 +15,10 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyAttribute(decoder, binary( + "00000000000000240d01060000001c642b3ad14754534c7c367c317c307c31323734393838347c317c0d0a010000ec11"), + Position.KEY_DRIVER_UNIQUE_ID, "12749884"); + verifyPositions(decoder, binary( "00000000000000a28e0100000183ac617e3001123eb99b1e142db4000000000000000000001d000900f000005000001503004500011e1801212d01242a012722012a18001100b5000000b600000018000000cd151000431c2d011f6981012047d701226981012347d901256981012647d8012869810129e6f304b0000304b1000304b2000304b30003000100f10000639d0002000b0000000214bf12fe000e0000000029d18c95000001000051b6")); -- cgit v1.2.3 From 5da3b8fcb480736161aa6a0896501f00f197bc13 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 6 Apr 2023 19:39:56 -0700 Subject: Decode 808 battery level --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 1 + src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index f13299169..1aebba4e6 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -538,6 +538,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); break; case 0xD4: + case 0xE1: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; case 0xD5: diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 4541185f4..67f214563 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( + "7e0200002f017028775424038d000000000000000a0189dbeb04ca653a00000012014723040700074401040000000030011b31010ee1012dea020001dc7e"), + Position.KEY_BATTERY_LEVEL, 45); + verifyAttribute(decoder, binary( "7E02000079013653183645009E00000000000C0C030158BF0006C926670000004000CE22120904274201040000005DBC3244524956494E47204C4943454E53452454455354244D522E0000000000000000000000000000000000000000000000000000BD0F323431393939393935383030313030E3060000050500007102000C30011F310108987E"), "driver", "DRIVING LICENSE$TEST$MR."); -- cgit v1.2.3 From ddf44c40b95c4a4a013f244ddffa3b1fad39d416 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 7 Apr 2023 07:01:27 -0700 Subject: Set LTE radio type --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 4968ed05e..969b24297 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -371,18 +371,19 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { Long cid4g = (Long) position.getAttributes().remove("cid4g"); Integer lac = (Integer) position.getAttributes().remove("lac"); if (lac != null && (cid2g != null || cid4g != null)) { + Network network = new Network(); CellTower cellTower; if (cid2g != null) { cellTower = CellTower.fromLacCid(getConfig(), lac, cid2g); - cellTower.setRadioType("gsm"); } else { cellTower = CellTower.fromLacCid(getConfig(), lac, cid4g); - cellTower.setRadioType("lte"); + network.setRadioType("lte"); } long operator = position.getInteger(Position.KEY_OPERATOR); if (operator >= 1000) { cellTower.setOperator(operator); } + network.addCellTower(cellTower); position.setNetwork(new Network(cellTower)); } } -- cgit v1.2.3 From dd8c46eec3282e344eeea5e27d084448c85e1518 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 10 Apr 2023 19:40:22 -0700 Subject: Add raw data forwarding --- src/main/java/org/traccar/BasePipelineFactory.java | 13 ++++- src/main/java/org/traccar/config/Keys.java | 7 +++ .../java/org/traccar/forward/NetworkForwarder.java | 66 ++++++++++++++++++++++ .../traccar/handler/NetworkForwarderHandler.java | 64 +++++++++++++++++++++ 4 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/traccar/forward/NetworkForwarder.java create mode 100644 src/main/java/org/traccar/handler/NetworkForwarderHandler.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 70f999c72..38b077980 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -36,6 +36,7 @@ import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.HemisphereHandler; import org.traccar.handler.MotionHandler; +import org.traccar.handler.NetworkForwarderHandler; import org.traccar.handler.NetworkMessageHandler; import org.traccar.handler.OpenChannelHandler; import org.traccar.handler.RemoteAddressHandler; @@ -60,15 +61,15 @@ public abstract class BasePipelineFactory extends ChannelInitializer { private final Injector injector; private final TrackerConnector connector; + private final Config config; private final String protocol; - private final boolean instantAcknowledgement; private final int timeout; public BasePipelineFactory(TrackerConnector connector, Config config, String protocol) { this.injector = Main.getInjector(); this.connector = connector; + this.config = config; this.protocol = protocol; - instantAcknowledgement = config.getBoolean(Keys.SERVER_INSTANT_ACKNOWLEDGEMENT); int timeout = config.getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); if (timeout == 0) { this.timeout = config.getInteger(Keys.SERVER_TIMEOUT); @@ -115,9 +116,15 @@ public abstract class BasePipelineFactory extends ChannelInitializer { pipeline.addLast(new IdleStateHandler(timeout, 0, 0)); } pipeline.addLast(new OpenChannelHandler(connector)); + if (config.hasKey(Keys.SERVER_FORWARD)) { + int port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); + var handler = new NetworkForwarderHandler(port); + injector.injectMembers(handler); + pipeline.addLast(handler); + } pipeline.addLast(new NetworkMessageHandler()); pipeline.addLast(new StandardLoggingHandler(protocol)); - if (!instantAcknowledgement) { + if (!config.getBoolean(Keys.SERVER_INSTANT_ACKNOWLEDGEMENT)) { pipeline.addLast(new AcknowledgementHandler()); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index b97acfd66..8ced32153 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -805,6 +805,13 @@ public final class Keys { List.of(KeyType.CONFIG), "max-age=3600,public"); + /** + * Host for raw data forwarding. + */ + public static final ConfigKey SERVER_FORWARD = new StringConfigKey( + "server.forward", + List.of(KeyType.CONFIG)); + /** * Position forwarding format. Available options are "url", "json" and "kafka". Default is "url". */ diff --git a/src/main/java/org/traccar/forward/NetworkForwarder.java b/src/main/java/org/traccar/forward/NetworkForwarder.java new file mode 100644 index 000000000..6abf2b7ba --- /dev/null +++ b/src/main/java/org/traccar/forward/NetworkForwarder.java @@ -0,0 +1,66 @@ +/* + * 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.forward; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.HashMap; +import java.util.Map; + +@Singleton +public class NetworkForwarder { + + private static final Logger LOGGER = LoggerFactory.getLogger(NetworkForwarder.class); + + private final InetAddress destination; + private final DatagramSocket connectionUdp; + private final Map connectionsTcp = new HashMap<>(); + + @Inject + public NetworkForwarder(Config config) throws IOException { + destination = InetAddress.getByName(config.getString(Keys.SERVER_FORWARD)); + connectionUdp = new DatagramSocket(); + } + + public void forward(InetSocketAddress source, int port, boolean datagram, byte[] data) { + try { + if (datagram) { + connectionUdp.send(new DatagramPacket(data, data.length, destination, port)); + } else { + Socket connectionTcp = connectionsTcp.get(source); + if (connectionTcp == null || connectionTcp.isClosed()) { + connectionTcp = new Socket(destination, port); + connectionsTcp.put(source, connectionTcp); + } + connectionTcp.getOutputStream().write(data); + } + } catch (IOException e) { + LOGGER.warn("Network forwarding error", e); + } + } + +} diff --git a/src/main/java/org/traccar/handler/NetworkForwarderHandler.java b/src/main/java/org/traccar/handler/NetworkForwarderHandler.java new file mode 100644 index 000000000..a3792a3e5 --- /dev/null +++ b/src/main/java/org/traccar/handler/NetworkForwarderHandler.java @@ -0,0 +1,64 @@ +/* + * 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.handler; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.DatagramPacket; +import org.traccar.forward.NetworkForwarder; + +import javax.inject.Inject; +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +public class NetworkForwarderHandler extends ChannelInboundHandlerAdapter { + + private final int port; + + private NetworkForwarder networkForwarder; + + public NetworkForwarderHandler(int port) { + this.port = port; + } + + @Inject + public void setNetworkForwarder(NetworkForwarder networkForwarder) { + this.networkForwarder = networkForwarder; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + boolean datagram = ctx.channel() instanceof DatagramChannel; + SocketAddress remoteAddress; + ByteBuf buffer; + if (datagram) { + DatagramPacket message = (DatagramPacket) msg; + remoteAddress = message.recipient(); + buffer = message.content(); + } else { + remoteAddress = ctx.channel().remoteAddress(); + buffer = (ByteBuf) msg; + } + + byte[] data = new byte[buffer.readableBytes()]; + buffer.getBytes(buffer.readerIndex(), data); + networkForwarder.forward((InetSocketAddress) remoteAddress, port, datagram, data); + super.channelRead(ctx, msg); + } + +} -- cgit v1.2.3 From d41d34de83ed755e0a51e5638e121391f84b275f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 11 Apr 2023 17:33:14 -0700 Subject: Support Nano firmware update --- .../org/traccar/protocol/Minifinder2Protocol.java | 6 +- .../protocol/Minifinder2ProtocolEncoder.java | 66 ++++++++++++++++++++++ .../protocol/Minifinder2ProtocolEncoderTest.java | 29 ++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java create mode 100644 src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index 5499a274e..61a43d8db 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 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. @@ -20,6 +20,7 @@ import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import org.traccar.model.Command; import java.nio.ByteOrder; @@ -29,10 +30,13 @@ public class Minifinder2Protocol extends BaseProtocol { @Inject public Minifinder2Protocol(Config config) { + setSupportedDataCommands( + Command.TYPE_FIRMWARE_UPDATE); addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1200, 2, 2, 4, 0, true)); + pipeline.addLast(new Minifinder2ProtocolEncoder(Minifinder2Protocol.this)); pipeline.addLast(new Minifinder2ProtocolDecoder(Minifinder2Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java new file mode 100644 index 000000000..ce7de6dfc --- /dev/null +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java @@ -0,0 +1,66 @@ +/* + * 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.buffer.Unpooled; +import org.traccar.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.helper.Checksum; +import org.traccar.model.Command; +import org.traccar.model.Device; + +import java.nio.charset.StandardCharsets; + +public class Minifinder2ProtocolEncoder extends BaseProtocolEncoder { + + public Minifinder2ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private ByteBuf encodeContent(ByteBuf content) { + + ByteBuf buf = Unpooled.buffer(); + + buf.writeByte(0xAB); // header + buf.writeByte(0x00); // properties + buf.writeShortLE(content.readableBytes()); + buf.writeShortLE(Checksum.crc16(Checksum.CRC16_XMODEM, content.nioBuffer())); + buf.writeShortLE(1); // index + buf.writeBytes(content); + + return buf; + } + + @Override + protected Object encodeCommand(Command command) { + + Device device = getCacheManager().getObject(Device.class, command.getDeviceId()); + if ("Nano".equalsIgnoreCase(device.getModel())) { + ByteBuf content = Unpooled.buffer(); + if (command.getType().equals(Command.TYPE_FIRMWARE_UPDATE)) { + String url = command.getString(Command.KEY_DATA); + content.writeByte(1 + url.length()); + content.writeByte(0x30); // type + content.writeCharSequence(url, StandardCharsets.US_ASCII); + return encodeContent(content); + } + } + + return null; + } + +} diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java new file mode 100644 index 000000000..a3477bfe8 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java @@ -0,0 +1,29 @@ +package org.traccar.protocol; + +import org.junit.jupiter.api.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; +import org.traccar.model.Device; + +import static org.mockito.Mockito.when; + +public class Minifinder2ProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncodeNano() throws Exception { + + var encoder = inject(new Minifinder2ProtocolEncoder(null)); + + var device = encoder.getCacheManager().getObject(Device.class, 1); + when(device.getModel()).thenReturn("Nano"); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_FIRMWARE_UPDATE); + command.set(Command.KEY_DATA, "https://example.com"); + + verifyCommand(encoder, command, binary("ab00150018750100143068747470733a2f2f6578616d706c652e636f6d")); + + } + +} -- cgit v1.2.3 From 5460739293ccd8e89adc9edb4653b4de28b09897 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 11 Apr 2023 19:28:43 -0700 Subject: Handle closed connections --- src/main/java/org/traccar/forward/NetworkForwarder.java | 11 +++++++++++ .../java/org/traccar/handler/NetworkForwarderHandler.java | 8 ++++++++ 2 files changed, 19 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/NetworkForwarder.java b/src/main/java/org/traccar/forward/NetworkForwarder.java index 6abf2b7ba..0915aaa27 100644 --- a/src/main/java/org/traccar/forward/NetworkForwarder.java +++ b/src/main/java/org/traccar/forward/NetworkForwarder.java @@ -63,4 +63,15 @@ public class NetworkForwarder { } } + public void disconnect(InetSocketAddress source) { + Socket connectionTcp = connectionsTcp.remove(source); + if (connectionTcp != null) { + try { + connectionTcp.close(); + } catch (IOException e) { + LOGGER.warn("Connection close error", e); + } + } + } + } diff --git a/src/main/java/org/traccar/handler/NetworkForwarderHandler.java b/src/main/java/org/traccar/handler/NetworkForwarderHandler.java index a3792a3e5..2c586c973 100644 --- a/src/main/java/org/traccar/handler/NetworkForwarderHandler.java +++ b/src/main/java/org/traccar/handler/NetworkForwarderHandler.java @@ -61,4 +61,12 @@ public class NetworkForwarderHandler extends ChannelInboundHandlerAdapter { super.channelRead(ctx, msg); } + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + if (!(ctx.channel() instanceof DatagramChannel)) { + networkForwarder.disconnect((InetSocketAddress) ctx.channel().remoteAddress()); + } + super.channelInactive(ctx); + } + } -- cgit v1.2.3 From 9a427527da45e599a1082f1f2836d195ea26acb5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 12 Apr 2023 17:14:22 -0700 Subject: Add iStartek SOS and door --- src/main/java/org/traccar/protocol/StartekProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index d75da7fbd..d08bb92a8 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -98,6 +98,8 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { private String decodeAlarm(int value) { switch (value) { + case 1: + return Position.ALARM_SOS; case 5: case 6: return Position.ALARM_DOOR; @@ -186,6 +188,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { int input = parser.nextHexInt(); int output = parser.nextHexInt(); position.set(Position.KEY_IGNITION, BitUtil.check(input, 1)); + position.set(Position.KEY_DOOR, BitUtil.check(input, 2)); position.set(Position.KEY_INPUT, input); position.set(Position.KEY_OUTPUT, output); -- cgit v1.2.3 From c024d09744dea2db2d60f51bc6c1532284ffca4e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Apr 2023 07:37:52 -0700 Subject: Fix Nano firmware update --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 2 ++ src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java | 1 + src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 37e86e243..f660f2e92 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -48,6 +48,8 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_DATA = 0x01; public static final int MSG_CONFIGURATION = 0x02; public static final int MSG_SERVICES = 0x03; + public static final int MSG_SYSTEM_CONTROL = 0x04; + public static final int MSG_FIRMWARE = 0x7E; public static final int MSG_RESPONSE = 0x7F; private String decodeAlarm(long code) { diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java index ce7de6dfc..fab3c3a6d 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolEncoder.java @@ -53,6 +53,7 @@ public class Minifinder2ProtocolEncoder extends BaseProtocolEncoder { ByteBuf content = Unpooled.buffer(); if (command.getType().equals(Command.TYPE_FIRMWARE_UPDATE)) { String url = command.getString(Command.KEY_DATA); + content.writeByte(Minifinder2ProtocolDecoder.MSG_SYSTEM_CONTROL); content.writeByte(1 + url.length()); content.writeByte(0x30); // type content.writeCharSequence(url, StandardCharsets.US_ASCII); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java index a3477bfe8..ef6ff6dd9 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolEncoderTest.java @@ -22,7 +22,7 @@ public class Minifinder2ProtocolEncoderTest extends ProtocolTest { command.setType(Command.TYPE_FIRMWARE_UPDATE); command.set(Command.KEY_DATA, "https://example.com"); - verifyCommand(encoder, command, binary("ab00150018750100143068747470733a2f2f6578616d706c652e636f6d")); + verifyCommand(encoder, command, binary("ab00160059d2010004143068747470733a2f2f6578616d706c652e636f6d")); } -- cgit v1.2.3 From 94280e2e63b02ae67482c85a388a58add85e10cf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 16 Apr 2023 12:54:38 -0700 Subject: Fix JXLS JEXL permissions --- .../reports/common/ExpressionEvaluatorFactory.java | 58 ++++++++++++++++++++++ .../org.jxls.expression.ExpressionEvaluatorFactory | 1 + 2 files changed, 59 insertions(+) create mode 100644 src/main/java/org/traccar/reports/common/ExpressionEvaluatorFactory.java create mode 100644 src/main/resources/META-INF/services/org.jxls.expression.ExpressionEvaluatorFactory (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ExpressionEvaluatorFactory.java b/src/main/java/org/traccar/reports/common/ExpressionEvaluatorFactory.java new file mode 100644 index 000000000..8b139a572 --- /dev/null +++ b/src/main/java/org/traccar/reports/common/ExpressionEvaluatorFactory.java @@ -0,0 +1,58 @@ +package org.traccar.reports.common; + +import org.apache.commons.jexl3.JexlBuilder; +import org.apache.commons.jexl3.introspection.JexlPermissions; +import org.jxls.expression.ExpressionEvaluator; +import org.jxls.expression.JexlExpressionEvaluator; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class ExpressionEvaluatorFactory implements org.jxls.expression.ExpressionEvaluatorFactory { + + private final JexlPermissions permissions = new JexlPermissions() { + @Override + public boolean allow(Package pack) { + return true; + } + + @Override + public boolean allow(Class clazz) { + return true; + } + + @Override + public boolean allow(Constructor ctor) { + return true; + } + + @Override + public boolean allow(Method method) { + return true; + } + + @Override + public boolean allow(Field field) { + return true; + } + + @Override + public JexlPermissions compose(String... src) { + return this; + } + }; + + @Override + public ExpressionEvaluator createExpressionEvaluator(String expression) { + JexlExpressionEvaluator expressionEvaluator = expression == null + ? new JexlExpressionEvaluator() + : new JexlExpressionEvaluator(expression); + expressionEvaluator.setJexlEngine(new JexlBuilder() + .silent(true) + .strict(false) + .permissions(permissions) + .create()); + return expressionEvaluator; + } +} diff --git a/src/main/resources/META-INF/services/org.jxls.expression.ExpressionEvaluatorFactory b/src/main/resources/META-INF/services/org.jxls.expression.ExpressionEvaluatorFactory new file mode 100644 index 000000000..75d628857 --- /dev/null +++ b/src/main/resources/META-INF/services/org.jxls.expression.ExpressionEvaluatorFactory @@ -0,0 +1 @@ +org.traccar.reports.common.ExpressionEvaluatorFactory -- cgit v1.2.3 From ab801e856521356ff7a33250e1abdb8857ef84b3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Apr 2023 06:29:50 -0700 Subject: Fix group commands --- src/main/java/org/traccar/api/resource/CommandResource.java | 6 ++++-- tools/test-commands.py | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 7ba1ee2b4..b69d4d9ac 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -28,6 +28,7 @@ import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; +import org.traccar.model.QueuedCommand; import org.traccar.model.Typed; import org.traccar.model.User; import org.traccar.model.UserRestrictions; @@ -121,8 +122,9 @@ public class CommandResource extends ExtendedObjectResource { permissionsService.checkPermission(Group.class, getUserId(), groupId); var devices = DeviceUtil.getAccessibleDevices(storage, getUserId(), List.of(), List.of(groupId)); for (Device device : devices) { - entity.setDeviceId(device.getId()); - result = result && commandsManager.sendCommand(entity); + Command command = QueuedCommand.fromCommand(entity).toCommand(); + command.setDeviceId(device.getId()); + result = result && commandsManager.sendCommand(command); } } else { permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); diff --git a/tools/test-commands.py b/tools/test-commands.py index 6e310051a..7efd963b4 100755 --- a/tools/test-commands.py +++ b/tools/test-commands.py @@ -6,9 +6,9 @@ import binascii s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("localhost", 5001)) #s.send(binascii.unhexlify('68680f0504035889905831401700df1a00000d0a')) -s.send("imei:123456789012345,tracker,151030080103,,F,000101.000,A,5443.3834,N,02512.9071,E,0.00,0;") +s.send(b"imei:123456789012345,tracker,151030080103,,F,000101.000,A,5443.3834,N,02512.9071,E,0.00,0;") while True: - print s.recv(1024) + print(s.recv(1024)) s.close() -- cgit v1.2.3 From 1d31ebe88f2674252fc2ab043349b900db5e5e2d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Apr 2023 08:52:10 -0700 Subject: Support BS51 messages --- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 119 ++++++++++++++------- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 3 + 2 files changed, 84 insertions(+), 38 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index 2b50e55c2..6c926da90 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -463,47 +463,90 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - ByteBuf buf = Unpooled.wrappedBuffer( - DataConverter.parseHex(sentence.substring(1 + 12 + 4, sentence.length() - 1))); - - buf.readUnsignedByte(); - buf.readUnsignedByte(); - buf.readUnsignedByte(); // header - - int batteryCount = buf.readUnsignedByte(); - for (int i = 1; i <= 24; i++) { - int voltage = buf.readUnsignedShortLE(); - if (i <= batteryCount) { - position.set("battery" + i, voltage * 0.001); + String payload = sentence.substring(1 + 12 + 4, sentence.length() - 1); + + if (sentence.startsWith("BS50", 1 + 12)) { + + ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(payload)); + + buf.readUnsignedByte(); + buf.readUnsignedByte(); + buf.readUnsignedByte(); // header + + int batteryCount = buf.readUnsignedByte(); + for (int i = 1; i <= 24; i++) { + int voltage = buf.readUnsignedShortLE(); + if (i <= batteryCount) { + position.set("battery" + i, voltage * 0.001); + } } - } - position.set(Position.KEY_CHARGE, buf.readUnsignedByte() == 0); - position.set("current", buf.readUnsignedShortLE() * 0.1); - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - position.set("batteryOverheat", buf.readUnsignedByte() > 0); - position.set("chargeProtection", buf.readUnsignedByte() > 0); - position.set("dischargeProtection", buf.readUnsignedByte() > 0); - buf.readUnsignedByte(); // drop line - buf.readUnsignedByte(); // balanced - position.set("cycles", buf.readUnsignedShortLE()); - position.set("faultAlarm", buf.readUnsignedByte()); - - buf.skipBytes(6); - - int temperatureCount = buf.readUnsignedByte(); - position.set("powerTemp", buf.readUnsignedByte() - 40); - position.set("equilibriumTemp", buf.readUnsignedByte() - 40); - for (int i = 1; i <= 7; i++) { - int temperature = buf.readUnsignedByte() - 40; - if (i <= temperatureCount) { - position.set("batteryTemp" + i, temperature); + position.set(Position.KEY_CHARGE, buf.readUnsignedByte() == 0); + position.set("current", buf.readUnsignedShortLE() * 0.1); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set("batteryOverheat", buf.readUnsignedByte() > 0); + position.set("chargeProtection", buf.readUnsignedByte() > 0); + position.set("dischargeProtection", buf.readUnsignedByte() > 0); + buf.readUnsignedByte(); // drop line + buf.readUnsignedByte(); // balanced + position.set("cycles", buf.readUnsignedShortLE()); + position.set("faultAlarm", buf.readUnsignedByte()); + + buf.skipBytes(6); + + int temperatureCount = buf.readUnsignedByte(); + position.set("powerTemp", buf.readUnsignedByte() - 40); + position.set("equilibriumTemp", buf.readUnsignedByte() - 40); + for (int i = 1; i <= 7; i++) { + int temperature = buf.readUnsignedByte() - 40; + if (i <= temperatureCount) { + position.set("batteryTemp" + i, temperature); + } } - } - position.set("calibrationCapacity", buf.readUnsignedShortLE() * 0.01); - position.set("dischargeCapacity", buf.readUnsignedIntLE()); + position.set("calibrationCapacity", buf.readUnsignedShortLE() * 0.01); + position.set("dischargeCapacity", buf.readUnsignedIntLE()); + + } else { + + String[] values = payload.split(","); + for (String value : values) { + String[] pair = value.split(":"); + int key = Integer.parseInt(pair[0], 16); + ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(pair[1])); + switch (key) { + case 0x90: + position.set("cumulativeVoltage", buf.readUnsignedShortLE() * 0.1); + position.set("gatherVoltage", buf.readUnsignedShortLE() * 0.1); + position.set("current", (buf.readUnsignedShortLE() - 30000) * 0.1); + position.set("soc", buf.readUnsignedShortLE() * 0.1); + break; + case 0x91: + position.set("maxCellVoltage", buf.readUnsignedShortLE() * 0.001); + position.set("maxCellVoltageCount", buf.readUnsignedByte()); + position.set("minCellVoltage", buf.readUnsignedShortLE() * 0.001); + position.set("minCellVoltageCount", buf.readUnsignedByte()); + break; + case 0x92: + position.set("maxTemp", buf.readUnsignedByte() - 40); + position.set("maxTempCount", buf.readUnsignedByte()); + position.set("minTemp", buf.readUnsignedByte() - 40); + position.set("minTempCount", buf.readUnsignedByte()); + break; + case 0x96: + buf.readUnsignedByte(); // frame + while (buf.isReadable()) { + position.set("cellTemp" + buf.readerIndex(), buf.readUnsignedByte() - 40); + } + break; + default: + break; + } + + } + + } return position; } @@ -537,7 +580,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return decodeLbsWifi(channel, remoteAddress, sentence); } else if (sentence.contains("BV00")) { return decodeVin(channel, remoteAddress, sentence); - } else if (sentence.contains("BS50")) { + } else if (sentence.contains("BS50") || sentence.contains("BS51")) { return decodeBms(channel, remoteAddress, sentence); } diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 1631ab051..a3b3fa86b 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Tk103ProtocolDecoder(null)); + verifyAttributes(decoder, text( + "(007030201454BS5190:02150000753001DC,91:0EE8060EDC0A01DC,92:42014201DC0A01DC,93:00010127000037C8,94:0E01000002000000,95:020EE10EE20EE800030EE40EE00EE700040EDD0EE40EE400050EDC0EDF0EE400,96:0142000000000000,97:0000000000000000,98:0000000000000000)")); + verifyAttribute(decoder, text( "(352602014867BS500064FF0EF10FF10FF00FF20FF30FF20FF20FF40FF20FF40FF40FF20FF30FF20F0000000000000000000000000000000000000000000000001663000000010004000000000000000002444444420000000000A00FA000000000000000200000000315E2000000)"), "batteryTemp2", 26); -- cgit v1.2.3 From beb43ba371de5862a7ca6579daef20c8ffd83f2d Mon Sep 17 00:00:00 2001 From: Aaron Donnelly Date: Thu, 20 Apr 2023 12:06:41 +0100 Subject: Teltonika io30 addition --- src/main/java/org/traccar/model/Position.java | 3 ++- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 2bd71f383..acb1026f2 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -23,7 +23,8 @@ import org.traccar.storage.StorageName; @StorageName("tc_positions") public class Position extends Message { - + + public static final String KEY_FAULT_COUNT = "faultCount"; public static final String KEY_ORIGINAL = "raw"; public static final String KEY_INDEX = "index"; public static final String KEY_HDOP = "hdop"; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 969b24297..7f692a30a 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -231,6 +231,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(26, null, (p, b) -> p.set("bleTemp2", b.readShort() * 0.01)); register(27, null, (p, b) -> p.set("bleTemp3", b.readShort() * 0.01)); register(28, null, (p, b) -> p.set("bleTemp4", b.readShort() * 0.01)); + register(30, fmbXXX, (p, b) -> p.set(Position.KEY_FAULT_COUNT, b.readUnsignedByte())); register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); -- cgit v1.2.3 From f92bde2088001c34186eb3897cece90171a319d1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Apr 2023 07:52:38 -0700 Subject: More ATrack binary parameters --- .../traccar/protocol/AtrackProtocolDecoder.java | 185 +++++++++++++++++++++ .../protocol/AtrackProtocolDecoderTest.java | 3 + 2 files changed, 188 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 340641729..aa19e9e41 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -429,6 +429,191 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { case "MP": buf.readUnsignedByte(); // manifold absolute pressure break; + case "EO": + position.set(Position.KEY_ODOMETER, UnitsConverter.metersFromMiles(buf.readUnsignedInt())); + break; + case "EH": + position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 360000); + break; + case "ZO1": + buf.readUnsignedByte(); // brake stroke status + break; + case "ZO2": + buf.readUnsignedByte(); // warning indicator status + break; + case "ZO3": + buf.readUnsignedByte(); // abs control status + break; + case "ZO4": + position.set(Position.KEY_THROTTLE, buf.readUnsignedByte() * 0.4); + break; + case "ZO5": + buf.readUnsignedByte(); // parking brake status + break; + case "ZO6": + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte() * 0.805); + break; + case "ZO7": + buf.readUnsignedByte(); // cruise control status + break; + case "ZO8": + buf.readUnsignedByte(); // accelector pedal position + break; + case "ZO9": + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte() * 0.5); + break; + case "ZO10": + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.5); + break; + case "ZO11": + buf.readUnsignedByte(); // engine oil pressure + break; + case "ZO12": + buf.readUnsignedByte(); // boost pressure + break; + case "ZO13": + buf.readUnsignedByte(); // intake temperature + break; + case "ZO14": + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte()); + break; + case "ZO15": + buf.readUnsignedByte(); // brake application pressure + break; + case "ZO16": + buf.readUnsignedByte(); // brake primary pressure + break; + case "ZO17": + buf.readUnsignedByte(); // brake secondary pressure + break; + case "ZH1": + buf.readUnsignedShort(); // cargo weight + break; + case "ZH2": + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 16.428 / 3600); + break; + case "ZH3": + position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.25); + break; + case "ZL1": + buf.readUnsignedInt(); // fuel used (natural gas) + break; + case "ZL2": + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 161); + break; + case "ZL3": + buf.readUnsignedInt(); // vehicle hours + break; + case "ZL4": + position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 5 * 36000); + break; + case "ZS1": + position.set(Position.KEY_VIN, readString(buf)); + break; + case "JO1": + buf.readUnsignedByte(); // pedals + break; + case "JO2": + buf.readUnsignedByte(); // power takeoff device + break; + case "JO3": + buf.readUnsignedByte(); // accelector pedal position + break; + case "JO4": + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); + break; + case "JO5": + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); + break; + case "JO6": + buf.readUnsignedByte(); // fms vehicle interface + break; + case "JO7": + buf.readUnsignedByte(); // driver 2 + break; + case "JO8": + buf.readUnsignedByte(); // driver 1 + break; + case "JO9": + buf.readUnsignedByte(); // drivers + break; + case "JO10": + buf.readUnsignedByte(); // system information + break; + case "JO11": + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + break; + case "JO12": + buf.readUnsignedByte(); // pto engaged + break; + case "JH1": + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() / 256.0); + break; + case "JH2": + position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125); + break; + case "JH3": + case "JH4": + case "JH5": + case "JH6": + case "JH7": + int index = Integer.parseInt(key.substring(2)) - 2; + position.set("axleWeight" + index, buf.readUnsignedShort() * 0.5); + break; + case "JH8": + position.set(Position.KEY_ODOMETER_SERVICE, buf.readUnsignedShort() * 5); + break; + case "JH9": + buf.readUnsignedShort(); // tachograph speed + break; + case "JH10": + buf.readUnsignedShort(); // ambient air temperature + break; + case "JH11": + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.05); + break; + case "JH12": + buf.readUnsignedShort(); // fuel economy + break; + case "JL1": + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.5); + break; + case "JL2": + position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 5 * 36000); + break; + case "JL3": + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + break; + case "JL4": + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.001); + break; + case "JS1": + position.set(Position.KEY_VIN, readString(buf)); + break; + case "JS2": + readString(buf); // fms version supported + break; + case "JS3": + position.set("driver1", readString(buf)); + break; + case "JS4": + position.set("driver2", readString(buf)); + break; + case "JN1": + buf.readUnsignedInt(); // cruise control distance + break; + case "JN2": + buf.readUnsignedInt(); // excessive idling time + break; + case "JN3": + buf.readUnsignedInt(); // excessive idling fuel + break; + case "JN4": + buf.readUnsignedInt(); // pto time + break; + case "JN5": + buf.readUnsignedInt(); // pto fuel + break; default: break; } diff --git a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java index dfdd3e579..32000c4a7 100644 --- a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -43,6 +43,9 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { decoder.setCustom(true); + verifyPositions(decoder, binary( + "405099280272000300014399e3f93d136438abdf644083f56440842afb2711c701b9eaee0067020003e0bb03de0000000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c3400000000000000000000000000000000000000000000930025000000000000000000000000000000006438abdf644083f76440842afb2711c701b9eaee0067710003e0bb03de0100000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c3400000000000000000000000000000000000000000000950025000000000000000000000000000000006438abdf644083f76440842afb2711c701b9eaee0067840003e0bb03de0100000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c3400000000000000000000000000000000000000000000950025000000000000000000000000000000006438abdf644083f86440842afb2711c701b9eaee0067760003e0bb03de0100000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c340000000000000000000000000000000000000000000095002500000000000000000000000000000000")); + verifyPositions(decoder, buffer( "@P,7A66,153,9022,863003048505515,20210207000103,20210207000103,20210207000103,103939276,1348903,97,2,5628,8,0,0,0,0,,2000,2000,\u001a,%CI%BC,3:224:F128833445E6002C09C6\r\n")); -- cgit v1.2.3 From c2637180549e69fc302f91f4685036e2697ae7bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Apr 2023 09:11:06 -0700 Subject: Fix report scheduling --- src/main/java/org/traccar/model/Calendar.java | 13 ++++++++++--- src/main/java/org/traccar/schedule/TaskReports.java | 12 +++++------- src/test/java/org/traccar/calendar/CalendarTest.java | 15 +++++++-------- 3 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index 62c51cc4a..03f1995ba 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -34,6 +34,7 @@ import java.time.Duration; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; @StorageName("tc_calendars") public class Calendar extends ExtendedModel { @@ -68,16 +69,22 @@ public class Calendar extends ExtendedModel { return calendar; } - public Collection findEvents(Date date) { + private Collection findEvents(Date date) { if (calendar != null) { - Period period = new Period(new DateTime(date), Duration.ZERO); - Filter filter = new Filter<>(new PeriodRule<>(period)); + var filter = new Filter(new PeriodRule<>(new Period(new DateTime(date), Duration.ZERO))); return filter.filter(calendar.getComponents(CalendarComponent.VEVENT)); } else { return List.of(); } } + public Collection findPeriods(Date date) { + var calendarDate = new net.fortuna.ical4j.model.Date(date); + return findEvents(date).stream() + .flatMap((event) -> event.getConsumedTime(calendarDate, calendarDate).stream()) + .collect(Collectors.toSet()); + } + public boolean checkMoment(Date date) { return !findEvents(date).isEmpty(); } diff --git a/src/main/java/org/traccar/schedule/TaskReports.java b/src/main/java/org/traccar/schedule/TaskReports.java index 004a6078c..176b6d537 100644 --- a/src/main/java/org/traccar/schedule/TaskReports.java +++ b/src/main/java/org/traccar/schedule/TaskReports.java @@ -18,7 +18,7 @@ package org.traccar.schedule; import com.google.inject.Injector; import com.google.inject.servlet.RequestScoper; import com.google.inject.servlet.ServletScopes; -import net.fortuna.ical4j.model.component.VEvent; +import net.fortuna.ical4j.model.Period; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.BaseModel; @@ -77,16 +77,14 @@ public class TaskReports implements ScheduleTask { Calendar calendar = storage.getObject(Calendar.class, new Request( new Columns.All(), new Condition.Equals("id", report.getCalendarId()))); - var lastEvents = calendar.findEvents(lastCheck); - var currentEvents = calendar.findEvents(currentCheck); + var lastEvents = calendar.findPeriods(lastCheck); + var currentEvents = calendar.findPeriods(currentCheck); if (!lastEvents.isEmpty() && currentEvents.isEmpty()) { - VEvent event = lastEvents.iterator().next(); - Date from = event.getStartDate().getDate(); - Date to = event.getEndDate().getDate(); + Period period = lastEvents.iterator().next(); RequestScoper scope = ServletScopes.scopeRequest(Collections.emptyMap()); try (RequestScoper.CloseableScope ignored = scope.open()) { - executeReport(report, from, to); + executeReport(report, period.getStart(), period.getEnd()); } } } diff --git a/src/test/java/org/traccar/calendar/CalendarTest.java b/src/test/java/org/traccar/calendar/CalendarTest.java index 6f4b30370..4106f89a9 100644 --- a/src/test/java/org/traccar/calendar/CalendarTest.java +++ b/src/test/java/org/traccar/calendar/CalendarTest.java @@ -11,6 +11,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class CalendarTest { @@ -45,14 +46,12 @@ public class CalendarTest { calendar.setData(calendarString.getBytes()); DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssX"); - Date date = format.parse("2016-12-13 22:59:59+05"); - assertTrue(!calendar.checkMoment(date)); - date = format.parse("2016-12-13 23:00:01+05"); - assertTrue(calendar.checkMoment(date)); + assertFalse(calendar.checkMoment(format.parse("2016-12-13 22:59:59+05"))); + assertTrue(calendar.checkMoment(format.parse("2016-12-13 23:00:01+05"))); + assertTrue(calendar.checkMoment(format.parse("2016-12-13 06:59:59+05"))); + assertFalse(calendar.checkMoment(format.parse("2016-12-13 07:00:01+05"))); - date = format.parse("2016-12-13 06:59:59+05"); - assertTrue(calendar.checkMoment(date)); - date = format.parse("2016-12-13 07:00:01+05"); - assertTrue(!calendar.checkMoment(date)); + var periods = calendar.findPeriods(format.parse("2016-12-13 06:59:59+05")); + assertFalse(periods.isEmpty()); } } -- cgit v1.2.3 From 30bafaed42e74863c5ca68a33c87f39d1e2de93d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 23 Apr 2023 08:29:22 -0700 Subject: Move geofenceIds to position --- schema/changelog-5.8.xml | 18 ++++++++ schema/changelog-master.xml | 1 + src/main/java/org/traccar/BasePipelineFactory.java | 2 + .../java/org/traccar/handler/GeofenceHandler.java | 52 ++++++++++++++++++++++ .../handler/events/GeofenceEventHandler.java | 41 +++++------------ .../handler/events/OverspeedEventHandler.java | 4 +- src/main/java/org/traccar/model/Device.java | 21 +-------- src/main/java/org/traccar/model/Position.java | 16 +++++++ swagger.json | 12 ++--- 9 files changed, 109 insertions(+), 58 deletions(-) create mode 100644 schema/changelog-5.8.xml create mode 100644 src/main/java/org/traccar/handler/GeofenceHandler.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.8.xml b/schema/changelog-5.8.xml new file mode 100644 index 000000000..ec54bf17f --- /dev/null +++ b/schema/changelog-5.8.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 1587cc789..dd2bcc8a7 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -38,5 +38,6 @@ + diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 38b077980..d04fed383 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -33,6 +33,7 @@ import org.traccar.handler.DistanceHandler; import org.traccar.handler.EngineHoursHandler; import org.traccar.handler.FilterHandler; import org.traccar.handler.GeocoderHandler; +import org.traccar.handler.GeofenceHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.HemisphereHandler; import org.traccar.handler.MotionHandler; @@ -149,6 +150,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { DistanceHandler.class, RemoteAddressHandler.class, FilterHandler.class, + GeofenceHandler.class, GeocoderHandler.class, SpeedLimitHandler.class, MotionHandler.class, diff --git a/src/main/java/org/traccar/handler/GeofenceHandler.java b/src/main/java/org/traccar/handler/GeofenceHandler.java new file mode 100644 index 000000000..fe15cef8e --- /dev/null +++ b/src/main/java/org/traccar/handler/GeofenceHandler.java @@ -0,0 +1,52 @@ +/* + * 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.handler; + +import io.netty.channel.ChannelHandler; +import org.traccar.BaseDataHandler; +import org.traccar.config.Config; +import org.traccar.helper.model.GeofenceUtil; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.List; + +@Singleton +@ChannelHandler.Sharable +public class GeofenceHandler extends BaseDataHandler { + + private final Config config; + private final CacheManager cacheManager; + + @Inject + public GeofenceHandler(Config config, CacheManager cacheManager) { + this.config = config; + this.cacheManager = cacheManager; + } + + @Override + protected Position handlePosition(Position position) { + + List geofenceIds = GeofenceUtil.getCurrentGeofences(config, cacheManager, position); + if (!geofenceIds.isEmpty()) { + position.setGeofenceIds(geofenceIds); + } + return position; + } + +} diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 9414f4b31..0ab9ca217 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 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 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. @@ -17,20 +17,14 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; import org.traccar.config.Config; -import org.traccar.helper.model.GeofenceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Calendar; -import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; @@ -59,36 +53,21 @@ public class GeofenceEventHandler extends BaseEventHandler { @Override protected Map analyzePosition(Position position) { - Device device = cacheManager.getObject(Device.class, position.getDeviceId()); - if (device == null) { - return null; - } - if (!PositionUtil.isLatest(cacheManager, position) || !position.getValid()) { + if (!PositionUtil.isLatest(cacheManager, position)) { return null; } - List currentGeofences = GeofenceUtil.getCurrentGeofences(config, cacheManager, position); List oldGeofences = new ArrayList<>(); - if (device.getGeofenceIds() != null) { - oldGeofences.addAll(device.getGeofenceIds()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + if (lastPosition != null && lastPosition.getGeofenceIds() != null) { + oldGeofences.addAll(lastPosition.getGeofenceIds()); } - List newGeofences = new ArrayList<>(currentGeofences); - newGeofences.removeAll(oldGeofences); - oldGeofences.removeAll(currentGeofences); - - - if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) { - device.setGeofenceIds(currentGeofences.isEmpty() ? null : currentGeofences); - - try { - storage.updateObject(device, new Request( - new Columns.Include("geofenceIds"), - new Condition.Equals("id", device.getId()))); - } catch (StorageException e) { - throw new RuntimeException("Update device geofences error", e); - } - connectionManager.updateDevice(true, device); + List newGeofences = new ArrayList<>(); + if (position.getGeofenceIds() != null) { + newGeofences.addAll(position.getGeofenceIds()); + newGeofences.removeAll(oldGeofences); + oldGeofences.removeAll(position.getGeofenceIds()); } Map events = new HashMap<>(); diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 4d6aa8857..40f1c7442 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -84,8 +84,8 @@ public class OverspeedEventHandler extends BaseEventHandler { double geofenceSpeedLimit = 0; long overspeedGeofenceId = 0; - if (device.getGeofenceIds() != null) { - for (long geofenceId : device.getGeofenceIds()) { + if (position.getGeofenceIds() != null) { + for (long geofenceId : position.getGeofenceIds()) { Geofence geofence = cacheManager.getObject(Geofence.class, geofenceId); if (geofence != null) { double currentSpeedLimit = geofence.getDouble(Keys.EVENT_OVERSPEED_LIMIT.getKey()); diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index b8c87921d..b7cffac49 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -15,14 +15,12 @@ */ package org.traccar.model; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; - import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; +import java.util.Date; + @StorageName("tc_devices") public class Device extends GroupedModel implements Disableable { @@ -83,21 +81,6 @@ public class Device extends GroupedModel implements Disableable { this.positionId = positionId; } - private List geofenceIds; - - @QueryIgnore - public List getGeofenceIds() { - return geofenceIds; - } - - public void setGeofenceIds(List geofenceIds) { - if (geofenceIds != null) { - this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); - } else { - this.geofenceIds = null; - } - } - private String phone; public String getPhone() { diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 2bd71f383..3ed340703 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -16,6 +16,8 @@ package org.traccar.model; import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.storage.QueryIgnore; @@ -309,6 +311,20 @@ public class Position extends Message { this.network = network; } + private List geofenceIds; + + public List getGeofenceIds() { + return geofenceIds; + } + + public void setGeofenceIds(List geofenceIds) { + if (geofenceIds != null) { + this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); + } else { + this.geofenceIds = null; + } + } + @JsonIgnore @QueryIgnore @Override diff --git a/swagger.json b/swagger.json index dde673e19..3d3842b67 100644 --- a/swagger.json +++ b/swagger.json @@ -2725,6 +2725,12 @@ "type": "object", "properties": {} }, + "geofenceIds": { + "type": "array", + "items": { + "type": "integer" + } + }, "attributes": { "type": "object", "properties": {} @@ -2927,12 +2933,6 @@ "category": { "type": "string" }, - "geofenceIds": { - "type": "array", - "items": { - "type": "integer" - } - }, "attributes": { "type": "object", "properties": {} -- cgit v1.2.3 From 2b3c1be84310e2c7c6a3dff4ec37be2560af772e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 24 Apr 2023 16:12:02 -0700 Subject: Fix report config issue --- src/main/java/org/traccar/reports/common/ReportUtils.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index f1a2f7d54..0c168e4ef 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -51,7 +51,6 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; -import javax.inject.Singleton; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -63,7 +62,6 @@ import java.util.Date; import java.util.List; import java.util.Locale; -@Singleton public class ReportUtils { private final Config config; -- cgit v1.2.3 From 03cebd3191a9c27c4b38e585b323d5c8d6868571 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 29 Apr 2023 13:56:51 -0700 Subject: Add outdated position filter --- src/main/java/org/traccar/config/Keys.java | 8 ++++++++ src/main/java/org/traccar/handler/FilterHandler.java | 9 +++++++++ 2 files changed, 17 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 8ced32153..c69289403 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1238,6 +1238,14 @@ public final class Keys { "filter.duplicate", List.of(KeyType.CONFIG)); + /** + * Filter messages that do not have GPS location. If they are not filtered, they will include the last known + * location. + */ + public static final ConfigKey FILTER_OUTDATED = new BooleanConfigKey( + "filter.outdated", + List.of(KeyType.CONFIG)); + /** * Filter records with fix time in the future. The value is specified in seconds. Records that have fix time more * than the specified number of seconds later than current server time would be filtered out. diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 1d1c27b7a..9ff94deb0 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -48,6 +48,7 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { private final boolean filterInvalid; private final boolean filterZero; private final boolean filterDuplicate; + private final boolean filterOutdated; private final long filterFuture; private final long filterPast; private final boolean filterApproximate; @@ -69,6 +70,7 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { filterInvalid = config.getBoolean(Keys.FILTER_INVALID); filterZero = config.getBoolean(Keys.FILTER_ZERO); filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE); + filterOutdated = config.getBoolean(Keys.FILTER_OUTDATED); filterFuture = config.getLong(Keys.FILTER_FUTURE) * 1000; filterPast = config.getLong(Keys.FILTER_PAST) * 1000; filterAccuracy = config.getInteger(Keys.FILTER_ACCURACY); @@ -115,6 +117,10 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { return false; } + private boolean filterOutdated(Position position) { + return filterOutdated && position.getOutdated(); + } + private boolean filterFuture(Position position) { return filterFuture != 0 && position.getFixTime().getTime() > System.currentTimeMillis() + filterFuture; } @@ -189,6 +195,9 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { if (filterZero(position)) { filterType.append("Zero "); } + if (filterOutdated(position)) { + filterType.append("Outdated "); + } if (filterFuture(position)) { filterType.append("Future "); } -- cgit v1.2.3 From 0f8dd92a6b1b9a288be888838a30195a6de41250 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 29 Apr 2023 14:20:38 -0700 Subject: Add X3 status sync --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 23 ++++++++++++++++++++++ .../traccar/protocol/Gt06ProtocolDecoderTest.java | 5 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 02a629103..7013533bc 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1028,6 +1028,29 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.01); return position; + } else if (subType == 0x04) { + + CharSequence content = buf.readCharSequence(buf.readableBytes() - 4 - 2, StandardCharsets.US_ASCII); + String[] values = content.toString().split(";"); + for (String value : values) { + String[] pair = value.split("="); + switch (pair[0]) { + case "ALM1": + case "ALM2": + case "ALM3": + position.set("alarm" + pair[0].charAt(3) + "Status", Integer.parseInt(pair[1], 16)); + case "STA1": + position.set("otherStatus", Integer.parseInt(pair[1], 16)); + break; + case "DYD": + position.set("engineStatus", Integer.parseInt(pair[1], 16)); + break; + default: + break; + } + } + return position; + } else if (subType == 0x05) { if (buf.readableBytes() >= 6 + 1 + 6) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 5dc6b803e..8f2c97f86 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttributes(decoder, binary( + "797900849404414c4d313d43353b414c4d323d43433b414c4d333d35433b535441313d43303b4459443d30313b534f533d303133323838333730302c2c3b43454e5445523d303133323838333730303b46454e43453d46656e63652c4f46462c302c302e3030303030302c302e3030303030302c3330302c494e206f72204f55542c313b00b79d120d0a")); + verifyAttribute(decoder, binary( "78782912170316053b3bcf015b51220af1201105d56100000000000000000000869c0130010000000238d1af0d0a"), Position.KEY_DRIVING_TIME, 0); @@ -190,7 +193,7 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, binary( "79790008940000ed0289d6860d0a")); - verifyNull(decoder, binary( + verifyAttributes(decoder, binary( "797900a59404414c4d313d34353b414c4d323d44353b414c4d333d35353b535441313d34303b4459443d30313b534f533d303538353036313536372c2c3b43454e5445523d3b46454e43453d46656e63652c4f46462c302c302e3030303030302c302e3030303030302c3330302c494e206f72204f55542c303b49434349443d38393937313033313031303038393539303432463b4d4f44453d4d4f44452c312c3138303b0008f65e0d0a")); verifyPosition(decoder, binary( -- cgit v1.2.3 From bb6964f03867d039a547c103cd16390f78688022 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 30 Apr 2023 11:49:28 -0700 Subject: Fix group commands (fix #5075) --- src/main/java/org/traccar/api/resource/CommandResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index b69d4d9ac..3df2244d1 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -124,7 +124,7 @@ public class CommandResource extends ExtendedObjectResource { for (Device device : devices) { Command command = QueuedCommand.fromCommand(entity).toCommand(); command.setDeviceId(device.getId()); - result = result && commandsManager.sendCommand(command); + result = commandsManager.sendCommand(command) && result; } } else { permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); -- cgit v1.2.3 From e73f36db83b9dc00a5dfe0a9625f40bd2698c3fa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 May 2023 13:59:35 -0700 Subject: Decode Escort fuel sensor --- src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index c7713bdc2..0135e78b7 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -978,7 +978,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { index += 1; // device type if (BitUtil.check(mask, 0)) { - index += 1; // digital fuel sensor data + position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(data[index++], 16)); } if (BitUtil.check(mask, 1)) { diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 515c14921..4b0edfd81 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "+BUFF:GTERI,410502,864802030794634,,00000001,,10,1,1,0.0,0,3027.8,-78.706612,-0.955699,20230418170736,0740,0002,A08C,2AB72D,00,0.0,,,,100,110000,1,0099,20230418171004,8B98$"), + Position.KEY_FUEL_LEVEL, 153); + verifyPositions(decoder, false, buffer( "+BUFF:GTFRI,2E0503,861106050005423,,,0,1,,,,,,,,,,,,0,0,,98,1,0,,,20200101000001,0083$")); -- cgit v1.2.3 From 3dad196b882c031e4ed36536c3b2deeb1b3bbff6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 4 May 2023 16:07:52 -0700 Subject: Extend HS-5000G OBD support --- src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java | 5 +++++ src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 2d952c759..2fb7c6e92 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -236,6 +236,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { while (buf.readableBytes() > 4) { int subtype = buf.readUnsignedShort(); int length = buf.readUnsignedShort() - 4; + int endIndex = buf.readerIndex() + length; switch (subtype) { case 0x0001: int coolantTemperature = buf.readUnsignedByte() - 40; @@ -253,6 +254,9 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); buf.readUnsignedInt(); // trip id + if (buf.readerIndex() < endIndex) { + position.set("adBlueLevel", buf.readUnsignedByte() * 0.4); + } break; case 0x0005: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); @@ -295,6 +299,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(length); break; } + buf.readerIndex(endIndex); } if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java index ee6c3fa7f..fe4b077c6 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java @@ -20,6 +20,9 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "c000000077aa0200000000000e000100143347315f48312e315f56312e30372e54000300133335353835353035303434303635380004000b3531323030303000050005010006000400070004000800050000090018383936313032353431343533333239313833360d000a000f796573696e7465726e6574c0")); + verifyNotNull(decoder, binary( + "c0000000b9aa00000000000013c800001132333035303431343537323600186bc30045e5b8002a008b0077002d000100187f0c4b2600d906ec000005938800000000000e0000040009110000000e0005000a1d0400000079000900154646464646464646464646464646464646000f00133836323230353035353339313733360010000c302e30303030303000110008000000000014000bf81b204901b52a001500060000002000153231394030324030403130343438393139c0")); + verifyAttribute(decoder, binary( "C00000001CAA120000000000020001001001000200030043008200C100C0"), Position.KEY_DTCS, "P0100 P0200 P0300 C0300 B0200 U0100"); -- cgit v1.2.3 From 445366d9a49fbee7a28a41e1f95423c07b54b725 Mon Sep 17 00:00:00 2001 From: K-J-Dod24 Date: Fri, 5 May 2023 14:29:50 +0100 Subject: io32 to coolant correcting io115 to engine temp --- src/main/java/org/traccar/model/Position.java | 1 + src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 3ed340703..c48e34e03 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -81,6 +81,7 @@ public class Position extends Message { public static final String KEY_ACCELERATION = "acceleration"; public static final String KEY_DEVICE_TEMP = "deviceTemp"; // celsius public static final String KEY_COOLANT_TEMP = "coolantTemp"; // celsius + public static final String KEY_ENGINE_TEMP = "engineTemp"; // celsius public static final String KEY_ENGINE_LOAD = "engineLoad"; public static final String KEY_OPERATOR = "operator"; public static final String KEY_COMMAND = "command"; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 969b24297..3cb89d6f7 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -231,6 +231,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(26, null, (p, b) -> p.set("bleTemp2", b.readShort() * 0.01)); register(27, null, (p, b) -> p.set("bleTemp3", b.readShort() * 0.01)); register(28, null, (p, b) -> p.set("bleTemp4", b.readShort() * 0.01)); + register(32, fmbXXX, (p, b) -> p.set(Position.KEY_COOLANT_TEMP, b.readByte())); register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); @@ -246,7 +247,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { }); register(80, fmbXXX, (p, b) -> p.set("dataMode", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); - register(115, fmbXXX, (p, b) -> p.set(Position.KEY_COOLANT_TEMP, b.readShort() * 0.1)); + register(115, fmbXXX, (p, b) -> p.set(Position.KEY_ENGINE_TEMP, b.readShort() * 0.1)); register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); register(181, null, (p, b) -> p.set(Position.KEY_PDOP, b.readUnsignedShort() * 0.1)); -- cgit v1.2.3 From 1e992e5f83cf97b13803098edec64d68f1843e91 Mon Sep 17 00:00:00 2001 From: Kieran Dodson <128472473+K-J-Dod24@users.noreply.github.com> Date: Tue, 9 May 2023 10:18:42 +0100 Subject: Revert "Teltonika io30 fault count" --- src/main/java/org/traccar/model/Position.java | 3 +-- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index be995ca2a..3ed340703 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -25,8 +25,7 @@ import org.traccar.storage.StorageName; @StorageName("tc_positions") public class Position extends Message { - - public static final String KEY_FAULT_COUNT = "faultCount"; + public static final String KEY_ORIGINAL = "raw"; public static final String KEY_INDEX = "index"; public static final String KEY_HDOP = "hdop"; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 7f692a30a..969b24297 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -231,7 +231,6 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(26, null, (p, b) -> p.set("bleTemp2", b.readShort() * 0.01)); register(27, null, (p, b) -> p.set("bleTemp3", b.readShort() * 0.01)); register(28, null, (p, b) -> p.set("bleTemp4", b.readShort() * 0.01)); - register(30, fmbXXX, (p, b) -> p.set(Position.KEY_FAULT_COUNT, b.readUnsignedByte())); register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); -- cgit v1.2.3 From 7b935f715761120a4149e6aaced7641314c53c47 Mon Sep 17 00:00:00 2001 From: K-J-Dod24 Date: Tue, 9 May 2023 14:01:44 +0100 Subject: io30 teltonika fault count --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 969b24297..fc18424df 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -231,6 +231,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(26, null, (p, b) -> p.set("bleTemp2", b.readShort() * 0.01)); register(27, null, (p, b) -> p.set("bleTemp3", b.readShort() * 0.01)); register(28, null, (p, b) -> p.set("bleTemp4", b.readShort() * 0.01)); + register(30, fmbXXX, (p, b) -> p.set("faultCount", b.readUnsignedByte())); register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); -- cgit v1.2.3 From 680fe003a7cc9da354a989936d8f7f07580110bb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 May 2023 07:35:17 -0700 Subject: Add Flespi event code --- src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index a7f6c284a..95d491af7 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -130,6 +130,9 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { case "dout": position.set(Position.KEY_OUTPUT, ((JsonNumber) value).intValue()); return true; + case "report.reason": + position.set(Position.KEY_EVENT, ((JsonNumber) value).intValue()); + return true; case "gps.vehicle.mileage": position.set(Position.KEY_ODOMETER, ((JsonNumber) value).doubleValue()); return true; -- cgit v1.2.3 From 1e8c232e37d0f041a8518cb4790322965bdd6fd5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 May 2023 07:51:41 -0700 Subject: Handle missing geofences --- .../handler/events/GeofenceEventHandler.java | 27 ++++++++-------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 0ab9ca217..096f71373 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -16,15 +16,12 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; -import org.traccar.config.Config; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Calendar; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; -import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; -import org.traccar.storage.Storage; import javax.inject.Inject; import javax.inject.Singleton; @@ -37,18 +34,11 @@ import java.util.Map; @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { - private final Config config; private final CacheManager cacheManager; - private final ConnectionManager connectionManager; - private final Storage storage; @Inject - public GeofenceEventHandler( - Config config, CacheManager cacheManager, ConnectionManager connectionManager, Storage storage) { - this.config = config; + public GeofenceEventHandler(CacheManager cacheManager) { this.cacheManager = cacheManager; - this.connectionManager = connectionManager; - this.storage = storage; } @Override @@ -72,12 +62,15 @@ public class GeofenceEventHandler extends BaseEventHandler { Map events = new HashMap<>(); for (long geofenceId : oldGeofences) { - long calendarId = cacheManager.getObject(Geofence.class, geofenceId).getCalendarId(); - Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; - if (calendar == null || calendar.checkMoment(position.getFixTime())) { - Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position); - event.setGeofenceId(geofenceId); - events.put(event, position); + Geofence geofence = cacheManager.getObject(Geofence.class, geofenceId); + if (geofence != null) { + long calendarId = geofence.getCalendarId(); + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; + if (calendar == null || calendar.checkMoment(position.getFixTime())) { + Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position); + event.setGeofenceId(geofenceId); + events.put(event, position); + } } } for (long geofenceId : newGeofences) { -- cgit v1.2.3 From e2402983eb53f6cd384cdd09cc0d217772023b9a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 May 2023 08:16:00 -0700 Subject: Expand transparent data --- .../traccar/protocol/HuabaoProtocolDecoder.java | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 1aebba4e6..f0b7cf6ca 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -877,6 +877,22 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x0539: position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); break; + case 0x052D: + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + break; + case 0x0530: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + break; + case 0x0535: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + break; + case 0x0536: + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + break; + case 0x0547: + case 0x0548: + position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); + break; default: switch (length) { case 1: @@ -898,6 +914,17 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { decodeCoordinates(position, buf); position.setTime(time); break; + case 0x02: + count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + buf.readUnsignedInt(); // system id + int codeCount = buf.readUnsignedShort(); + for (int j = 0; j < codeCount; j++) { + buf.skipBytes(16); // code + } + } + decodeCoordinates(position, buf); + break; case 0x03: count = buf.readUnsignedByte(); for (int i = 0; i < count; i++) { -- cgit v1.2.3 From 4c57f717f678969a46d9d84538a3116018dce9c1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 May 2023 08:19:24 -0700 Subject: Use last location info --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index f0b7cf6ca..fcbb55043 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -911,8 +911,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { break; } } + getLastLocation(position, time); decodeCoordinates(position, buf); - position.setTime(time); break; case 0x02: count = buf.readUnsignedByte(); @@ -923,6 +923,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(16); // code } } + getLastLocation(position, time); decodeCoordinates(position, buf); break; case 0x03: @@ -953,8 +954,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } buf.skipBytes(length); } + getLastLocation(position, time); decodeCoordinates(position, buf); - position.setTime(time); break; case 0x0B: if (buf.readUnsignedByte() > 0) { -- cgit v1.2.3 From d797671b2ce6fb70ac868bb96f87be8b2a85e4f9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 May 2023 08:23:16 -0700 Subject: Fix unit tests --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index fcbb55043..05e2fb8cc 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -913,6 +913,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } getLastLocation(position, time); decodeCoordinates(position, buf); + position.setTime(time); break; case 0x02: count = buf.readUnsignedByte(); @@ -925,6 +926,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } getLastLocation(position, time); decodeCoordinates(position, buf); + position.setTime(time); break; case 0x03: count = buf.readUnsignedByte(); @@ -956,6 +958,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } getLastLocation(position, time); decodeCoordinates(position, buf); + position.setTime(time); break; case 0x0B: if (buf.readUnsignedByte() > 0) { -- cgit v1.2.3 From ae1205dfdded530e4cdf7bb665fe52cf197c33be Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 10 May 2023 07:33:05 -0700 Subject: Fix Huabao event decoding --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 8 ++++---- src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 05e2fb8cc..ed71861a5 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -333,10 +333,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // power level position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; - case 0x60: - position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - buf.skipBytes(length - 2); - break; case 0x61: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); break; @@ -488,6 +484,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, Integer.parseInt(lockStatus.substring(2, 5)) * 0.01); } break; + case 0x60: + position.set(Position.KEY_EVENT, buf.readUnsignedShort()); + buf.skipBytes(length - 2); + break; case 0x80: buf.readUnsignedByte(); // content endIndex = buf.writerIndex() - 2; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 67f214563..32c632353 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( + "7e02000071768060874297002d0000000000208022015a30b006c869f8000000000000230505062034600b0004003930303235343939660b01cc0000000c40f89f27b067083133323134333232690201936a01116b01006c0f34363030383138353937303632343071143839383630343938313032313930353835373430607e"), + Position.KEY_EVENT, 4); + verifyAttribute(decoder, binary( "7e0200002f017028775424038d000000000000000a0189dbeb04ca653a00000012014723040700074401040000000030011b31010ee1012dea020001dc7e"), Position.KEY_BATTERY_LEVEL, 45); -- cgit v1.2.3 From 46f09ad36017e9ac160cf029551dc2586f21504f Mon Sep 17 00:00:00 2001 From: Zeus The Developer <75146431+zeustd@users.noreply.github.com> Date: Wed, 10 May 2023 20:24:42 +0530 Subject: Add VL502 Alarms Added support for VL502 additional alarms, Protocol document Page 44, 0x03 --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index ed71861a5..2c6f9af96 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -951,6 +951,21 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x23: position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); break; + case 0x26: + case 0x27: + case 0x28: + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + break; + case 0x31: + case 0x32: + position.set(Position.KEY_ALARM, Position.ALARM_DOOR); + break; + case 0x01: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + break; + case 0x02: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; default: break; } -- cgit v1.2.3 From c3fe534d28c35d252ca97d99ae1b4d1fbe87d2f0 Mon Sep 17 00:00:00 2001 From: Zeus The Developer <75146431+zeustd@users.noreply.github.com> Date: Wed, 10 May 2023 20:34:54 +0530 Subject: Update case by order id Sort cases by order id --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 2c6f9af96..e6980dc28 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -934,6 +934,12 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { int id = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); switch (id) { + case 0x01: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + break; + case 0x02: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; case 0x1A: position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); break; @@ -960,12 +966,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x32: position.set(Position.KEY_ALARM, Position.ALARM_DOOR); break; - case 0x01: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case 0x02: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; default: break; } -- cgit v1.2.3 From 22c86a7096743ef592facd36f1ddcc756eb0459b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 11 May 2023 07:51:47 -0700 Subject: Increase iStartek frame limit --- src/main/java/org/traccar/protocol/StartekProtocol.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/StartekProtocol.java b/src/main/java/org/traccar/protocol/StartekProtocol.java index d010df858..1b1c93e33 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocol.java +++ b/src/main/java/org/traccar/protocol/StartekProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 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. @@ -38,7 +38,7 @@ public class StartekProtocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new LineBasedFrameDecoder(1100)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StartekProtocolEncoder(StartekProtocol.this)); -- cgit v1.2.3 From f68d23d79d0321ef47f72fff2388b5f4aac1beff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 May 2023 10:28:44 -0700 Subject: Per device motion threshold --- src/main/java/org/traccar/config/Keys.java | 2 +- src/main/java/org/traccar/handler/MotionHandler.java | 16 ++++++++++------ .../java/org/traccar/reports/common/TripsConfig.java | 12 ++---------- src/test/java/org/traccar/handler/MotionHandlerTest.java | 16 ++++++++++++---- .../traccar/handler/events/MotionEventHandlerTest.java | 6 +++--- src/test/java/org/traccar/reports/ReportUtilsTest.java | 16 ++++++++-------- 6 files changed, 36 insertions(+), 32 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index c69289403..f0e0bf2b6 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -380,7 +380,7 @@ public final class Keys { */ public static final ConfigKey EVENT_MOTION_SPEED_THRESHOLD = new DoubleConfigKey( "event.motion.speedThreshold", - List.of(KeyType.CONFIG), + List.of(KeyType.CONFIG, KeyType.DEVICE), 0.01); /** diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 10312f9b3..297527b4d 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 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,8 +18,10 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Position; -import org.traccar.reports.common.TripsConfig; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.inject.Singleton; @@ -28,17 +30,19 @@ import javax.inject.Singleton; @ChannelHandler.Sharable public class MotionHandler extends BaseDataHandler { - private final double speedThreshold; + private final CacheManager cacheManager; @Inject - public MotionHandler(TripsConfig tripsConfig) { - speedThreshold = tripsConfig.getSpeedThreshold(); + public MotionHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Position handlePosition(Position position) { if (!position.hasAttribute(Position.KEY_MOTION)) { - position.set(Position.KEY_MOTION, position.getSpeed() > speedThreshold); + double threshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_MOTION_SPEED_THRESHOLD, position.getDeviceId()); + position.set(Position.KEY_MOTION, position.getSpeed() > threshold); } return position; } diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java index 52db97b74..841d9c652 100644 --- a/src/main/java/org/traccar/reports/common/TripsConfig.java +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -33,20 +33,18 @@ public class TripsConfig { config.getLong(Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION) * 1000, config.getLong(Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION) * 1000, config.getBoolean(Keys.REPORT_TRIP_USE_IGNITION), - config.getBoolean(Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS), - config.getDouble(Keys.EVENT_MOTION_SPEED_THRESHOLD)); + config.getBoolean(Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS)); } public TripsConfig( double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, - long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { + long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; this.minimalNoDataDuration = minimalNoDataDuration; this.useIgnition = useIgnition; this.processInvalidPositions = processInvalidPositions; - this.speedThreshold = speedThreshold; } private final double minimalTripDistance; @@ -85,10 +83,4 @@ public class TripsConfig { return processInvalidPositions; } - private final double speedThreshold; - - public double getSpeedThreshold() { - return speedThreshold; - } - } diff --git a/src/test/java/org/traccar/handler/MotionHandlerTest.java b/src/test/java/org/traccar/handler/MotionHandlerTest.java index 2a7af23ba..10cdf6a90 100644 --- a/src/test/java/org/traccar/handler/MotionHandlerTest.java +++ b/src/test/java/org/traccar/handler/MotionHandlerTest.java @@ -1,10 +1,15 @@ package org.traccar.handler; import org.junit.jupiter.api.Test; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Device; import org.traccar.model.Position; -import org.traccar.reports.common.TripsConfig; +import org.traccar.session.cache.CacheManager; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -13,10 +18,13 @@ public class MotionHandlerTest { @Test public void testCalculateMotion() { - TripsConfig tripsConfig = mock(TripsConfig.class); - when(tripsConfig.getSpeedThreshold()).thenReturn(0.01); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(mock(Device.class)); + var config = mock(Config.class); + when(config.getString(Keys.EVENT_MOTION_SPEED_THRESHOLD.getKey())).thenReturn("0.01"); + when(cacheManager.getConfig()).thenReturn(config); - MotionHandler motionHandler = new MotionHandler(tripsConfig); + MotionHandler motionHandler = new MotionHandler(cacheManager); Position position = motionHandler.handlePosition(new Position()); diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index f2d858656..2be3f4647 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -36,7 +36,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws ParseException { - TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false); MotionState state = new MotionState(); @@ -63,7 +63,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionFluctuation() throws ParseException { - TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false); MotionState state = new MotionState(); @@ -94,7 +94,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testStopWithPositionIgnition() throws ParseException { - TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false); MotionState state = new MotionState(); state.setMotionStreak(true); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 09e5b3e27..e116f24b4 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -101,7 +101,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:15:00.000", 0, 3000), position("2016-01-01 00:25:00.000", 0, 3000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); @@ -156,7 +156,7 @@ public class ReportUtilsTest extends BaseTest { data.get(5).set(Position.KEY_IGNITION, false); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); @@ -227,7 +227,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:19:00.000", 0, 7000), position("2016-01-01 00:29:00.000", 0, 7000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); @@ -278,7 +278,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); @@ -307,7 +307,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); @@ -336,7 +336,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:22:00.000", 0, 0), position("2016-01-01 00:32:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); @@ -365,7 +365,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); @@ -390,7 +390,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); - TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); + TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); -- cgit v1.2.3 From a96a75cc268f2819431b7441090052b01bf61bed Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 May 2023 14:07:50 -0700 Subject: Per device trip config --- src/main/java/org/traccar/config/Keys.java | 12 +-- .../traccar/handler/events/MotionEventHandler.java | 14 +-- .../org/traccar/helper/model/AttributeUtil.java | 106 +++++++++++++++++++-- .../org/traccar/reports/common/ReportUtils.java | 7 +- .../org/traccar/reports/common/TripsConfig.java | 31 ++---- .../handler/events/MotionEventHandlerTest.java | 6 +- .../java/org/traccar/reports/ReportUtilsTest.java | 86 +++++++++-------- 7 files changed, 176 insertions(+), 86 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index f0e0bf2b6..432182fdd 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -373,7 +373,7 @@ public final class Keys { */ public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "event.motion.processInvalidPositions", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG, KeyType.DEVICE)); /** * If the speed is above specified value, the object is considered to be in motion. Default value is 0.01 knots. @@ -1167,7 +1167,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DISTANCE = new LongConfigKey( "report.trip.minimalTripDistance", - List.of(KeyType.CONFIG), + List.of(KeyType.CONFIG, KeyType.DEVICE), 500L); /** @@ -1175,7 +1175,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DURATION = new LongConfigKey( "report.trip.minimalTripDuration", - List.of(KeyType.CONFIG), + List.of(KeyType.CONFIG, KeyType.DEVICE), 300L); /** @@ -1183,7 +1183,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_PARKING_DURATION = new LongConfigKey( "report.trip.minimalParkingDuration", - List.of(KeyType.CONFIG), + List.of(KeyType.CONFIG, KeyType.DEVICE), 300L); /** @@ -1191,7 +1191,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_NO_DATA_DURATION = new LongConfigKey( "report.trip.minimalNoDataDuration", - List.of(KeyType.CONFIG), + List.of(KeyType.CONFIG, KeyType.DEVICE), 3600L); /** @@ -1199,7 +1199,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_USE_IGNITION = new BooleanConfigKey( "report.trip.useIgnition", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG, KeyType.DEVICE)); /** * Ignore odometer value reported by the device and use server-calculated total distance instead. This is useful diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index c406bd935..63b512291 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 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,6 +19,8 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; @@ -46,14 +48,12 @@ public class MotionEventHandler extends BaseEventHandler { private final CacheManager cacheManager; private final Storage storage; - private final TripsConfig tripsConfig; @Inject public MotionEventHandler( CacheManager cacheManager, Storage storage, TripsConfig tripsConfig) { this.cacheManager = cacheManager; this.storage = storage; - this.tripsConfig = tripsConfig; } @Override @@ -61,14 +61,16 @@ public class MotionEventHandler extends BaseEventHandler { long deviceId = position.getDeviceId(); Device device = cacheManager.getObject(Device.class, deviceId); - if (device == null) { + if (device == null || !PositionUtil.isLatest(cacheManager, position)) { return null; } - if (!PositionUtil.isLatest(cacheManager, position) - || !tripsConfig.getProcessInvalidPositions() && !position.getValid()) { + boolean processInvalid = AttributeUtil.lookup( + cacheManager, Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS, deviceId); + if (!processInvalid && !position.getValid()) { return null; } + TripsConfig tripsConfig = new TripsConfig(new AttributeUtil.CacheProvider(cacheManager, deviceId)); MotionState state = MotionState.fromDevice(device); MotionProcessor.updateState(state, position, position.getBoolean(Position.KEY_MOTION), tripsConfig); if (state.isChanged()) { diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 43558e8f7..2630f64f0 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -15,25 +15,44 @@ */ package org.traccar.helper.model; +import org.traccar.api.security.PermissionsService; +import org.traccar.config.Config; import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.model.Group; +import org.traccar.model.Server; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; public final class AttributeUtil { private AttributeUtil() { } - @SuppressWarnings({ "deprecation", "unchecked" }) + public interface Provider { + Device getDevice(); + Group getGroup(long groupId); + Server getServer(); + Config getConfig(); + } + public static T lookup(CacheManager cacheManager, ConfigKey key, long deviceId) { - Device device = cacheManager.getObject(Device.class, deviceId); + return lookup(new CacheProvider(cacheManager, deviceId), key); + } + + @SuppressWarnings({ "deprecation", "unchecked" }) + public static T lookup(Provider provider, ConfigKey key) { + Device device = provider.getDevice(); Object result = device.getAttributes().get(key.getKey()); long groupId = device.getGroupId(); while (result == null && groupId > 0) { - Group group = cacheManager.getObject(Group.class, groupId); + Group group = provider.getGroup(groupId); if (group != null) { result = group.getAttributes().get(key.getKey()); groupId = group.getGroupId(); @@ -42,10 +61,10 @@ public final class AttributeUtil { } } if (result == null && key.hasType(KeyType.SERVER)) { - result = cacheManager.getServer().getAttributes().get(key.getKey()); + result = provider.getServer().getAttributes().get(key.getKey()); } if (result == null && key.hasType(KeyType.CONFIG)) { - result = cacheManager.getConfig().getString(key.getKey()); + result = provider.getConfig().getString(key.getKey()); } if (result != null) { @@ -91,4 +110,79 @@ public final class AttributeUtil { return defaultPassword; } + public static class CacheProvider implements Provider { + + private final CacheManager cacheManager; + private final long deviceId; + + public CacheProvider(CacheManager cacheManager, long deviceId) { + this.cacheManager = cacheManager; + this.deviceId = deviceId; + } + + @Override + public Device getDevice() { + return cacheManager.getObject(Device.class, deviceId); + } + + @Override + public Group getGroup(long groupId) { + return cacheManager.getObject(Group.class, groupId); + } + + @Override + public Server getServer() { + return cacheManager.getServer(); + } + + @Override + public Config getConfig() { + return cacheManager.getConfig(); + } + } + + public static class StorageProvider implements Provider { + + private final Config config; + private final Storage storage; + private final PermissionsService permissionsService; + private final Device device; + + public StorageProvider(Config config, Storage storage, PermissionsService permissionsService, Device device) { + this.config = config; + this.storage = storage; + this.permissionsService = permissionsService; + this.device = device; + } + + @Override + public Device getDevice() { + return device; + } + + @Override + public Group getGroup(long groupId) { + try { + return storage.getObject( + Group.class, new Request(new Columns.All(), new Condition.Equals("id", groupId))); + } catch (StorageException e) { + throw new RuntimeException(e); + } + } + + @Override + public Server getServer() { + try { + return permissionsService.getServer(); + } catch (StorageException e) { + throw new RuntimeException(e); + } + } + + @Override + public Config getConfig() { + return config; + } + } + } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 0c168e4ef..f5aa6d040 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,6 +31,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.geocoder.Geocoder; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; @@ -67,18 +68,16 @@ public class ReportUtils { private final Config config; private final Storage storage; private final PermissionsService permissionsService; - private final TripsConfig tripsConfig; private final VelocityEngine velocityEngine; private final Geocoder geocoder; @Inject public ReportUtils( Config config, Storage storage, PermissionsService permissionsService, - TripsConfig tripsConfig, VelocityEngine velocityEngine, @Nullable Geocoder geocoder) { + VelocityEngine velocityEngine, @Nullable Geocoder geocoder) { this.config = config; this.storage = storage; this.permissionsService = permissionsService; - this.tripsConfig = tripsConfig; this.velocityEngine = velocityEngine; this.geocoder = geocoder; } @@ -306,6 +305,8 @@ public class ReportUtils { Class reportClass) throws StorageException { Collection result = new ArrayList<>(); + TripsConfig tripsConfig = new TripsConfig( + new AttributeUtil.StorageProvider(config, storage, permissionsService, device)); ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java index 841d9c652..2792114d4 100644 --- a/src/main/java/org/traccar/reports/common/TripsConfig.java +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,35 +16,28 @@ */ package org.traccar.reports.common; -import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton public class TripsConfig { - @Inject - public TripsConfig(Config config) { + public TripsConfig(AttributeUtil.Provider attributeProvider) { this( - config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DISTANCE), - config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DURATION) * 1000, - config.getLong(Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION) * 1000, - config.getLong(Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION) * 1000, - config.getBoolean(Keys.REPORT_TRIP_USE_IGNITION), - config.getBoolean(Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS)); + AttributeUtil.lookup(attributeProvider, Keys.REPORT_TRIP_MINIMAL_TRIP_DISTANCE), + AttributeUtil.lookup(attributeProvider, Keys.REPORT_TRIP_MINIMAL_TRIP_DURATION) * 1000, + AttributeUtil.lookup(attributeProvider, Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION) * 1000, + AttributeUtil.lookup(attributeProvider, Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION) * 1000, + AttributeUtil.lookup(attributeProvider, Keys.REPORT_TRIP_USE_IGNITION)); } public TripsConfig( double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, - long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions) { + long minimalNoDataDuration, boolean useIgnition) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; this.minimalNoDataDuration = minimalNoDataDuration; this.useIgnition = useIgnition; - this.processInvalidPositions = processInvalidPositions; } private final double minimalTripDistance; @@ -77,10 +70,4 @@ public class TripsConfig { return useIgnition; } - private final boolean processInvalidPositions; - - public boolean getProcessInvalidPositions() { - return processInvalidPositions; - } - } diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 2be3f4647..c61ae913d 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -36,7 +36,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws ParseException { - TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false); MotionState state = new MotionState(); @@ -63,7 +63,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionFluctuation() throws ParseException { - TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false); MotionState state = new MotionState(); @@ -94,7 +94,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testStopWithPositionIgnition() throws ParseException { - TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true); MotionState state = new MotionState(); state.setMotionStreak(true); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index e116f24b4..22d70c93a 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -2,15 +2,16 @@ package org.traccar.reports; import org.apache.velocity.app.VelocityEngine; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; @@ -24,6 +25,7 @@ import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.TimeZone; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -62,6 +64,19 @@ public class ReportUtilsTest extends BaseTest { return position; } + + private Device mockDevice( + double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, + long minimalNoDataDuration, boolean useIgnition) { + Device device = mock(Device.class); + when(device.getAttributes()).thenReturn(Map.of( + Keys.REPORT_TRIP_MINIMAL_TRIP_DISTANCE.getKey(), minimalTripDistance, + Keys.REPORT_TRIP_MINIMAL_TRIP_DURATION.getKey(), minimalTripDuration, + Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION.getKey(), minimalParkingDuration, + Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION.getKey(), minimalNoDataDuration, + Keys.REPORT_TRIP_USE_IGNITION.getKey(), useIgnition)); + return device; + } @Test public void testCalculateDistance() { @@ -78,8 +93,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testCalculateSpentFuel() { ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - mock(TripsConfig.class), mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); Position startPosition = new Position(); Position endPosition = new Position(); assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); @@ -101,12 +115,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:15:00.000", 0, 3000), position("2016-01-01 00:25:00.000", 0, 3000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); + Device device = mockDevice(500, 300, 180, 900, false); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(mock(Device.class), data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -120,7 +133,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -156,12 +169,11 @@ public class ReportUtilsTest extends BaseTest { data.get(5).set(Position.KEY_IGNITION, false); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false); + Device device = mockDevice(500, 300, 180, 900, true); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -175,7 +187,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -189,7 +201,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -227,12 +239,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:19:00.000", 0, 7000), position("2016-01-01 00:29:00.000", 0, 7000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); + Device device = mockDevice(500, 300, 180, 900, false); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -246,7 +257,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -278,12 +289,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -307,12 +317,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -336,12 +345,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:22:00.000", 0, 0), position("2016-01-01 00:32:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -365,12 +373,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -390,12 +397,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); - TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false); + Device device = mockDevice(500, 200, 200, 900, false); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), storage, mock(PermissionsService.class), - tripsConfig, mock(VelocityEngine.class), null); + mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -409,7 +415,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 454abd506ac6e1865ece67b534805253e7e63337 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 May 2023 14:08:44 -0700 Subject: Fix injection issue --- src/main/java/org/traccar/handler/events/MotionEventHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 63b512291..d2c54ccf3 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -50,8 +50,7 @@ public class MotionEventHandler extends BaseEventHandler { private final Storage storage; @Inject - public MotionEventHandler( - CacheManager cacheManager, Storage storage, TripsConfig tripsConfig) { + public MotionEventHandler(CacheManager cacheManager, Storage storage) { this.cacheManager = cacheManager; this.storage = storage; } -- cgit v1.2.3 From b9b2c5c111a56acfab6ac6b5c314f6f0dcb9baec Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 May 2023 14:14:23 -0700 Subject: Fix default boolean values --- src/main/java/org/traccar/config/Keys.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 432182fdd..162a3fe13 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -373,7 +373,8 @@ public final class Keys { */ public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "event.motion.processInvalidPositions", - List.of(KeyType.CONFIG, KeyType.DEVICE)); + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); /** * If the speed is above specified value, the object is considered to be in motion. Default value is 0.01 knots. @@ -1199,7 +1200,8 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_USE_IGNITION = new BooleanConfigKey( "report.trip.useIgnition", - List.of(KeyType.CONFIG, KeyType.DEVICE)); + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); /** * Ignore odometer value reported by the device and use server-calculated total distance instead. This is useful @@ -1207,7 +1209,8 @@ public final class Keys { */ public static final ConfigKey REPORT_IGNORE_ODOMETER = new BooleanConfigKey( "report.ignoreOdometer", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), + false); /** * Boolean flag to enable or disable position filtering. -- cgit v1.2.3 From 553527d9fbe689be243acbf219bed432f15c25e3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 15 May 2023 07:40:15 -0700 Subject: Decode HHDLink power --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 3 +++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index e6980dc28..4beee7696 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -488,6 +488,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_EVENT, buf.readUnsignedShort()); buf.skipBytes(length - 2); break; + case 0x69: + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + break; case 0x80: buf.readUnsignedByte(); // content endIndex = buf.writerIndex() - 2; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 32c632353..2f317d049 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( + "7e0200006476806111898300710000000000100046005d3156065f7128000000000000230511165956660b01fe000001031a5d1a8101670831333231343332326902018b6a01166b01006c0f323034303830393230373533363735711438393434343738383030303030323131303030464b7e"), + Position.KEY_BATTERY, 3.95); + verifyAttribute(decoder, binary( "7e02000071768060874297002d0000000000208022015a30b006c869f8000000000000230505062034600b0004003930303235343939660b01cc0000000c40f89f27b067083133323134333232690201936a01116b01006c0f34363030383138353937303632343071143839383630343938313032313930353835373430607e"), Position.KEY_EVENT, 4); -- cgit v1.2.3 From 6dae98179630a15c5f62899b32ed093e293822e2 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Mon, 15 May 2023 19:42:22 +0300 Subject: Add [Protocol]TranSyncProtocol Add TranSyncProtocol.java Add TranSyncProtocolDecoder.java Add TranSyncProtocolDecoderTest.java --- .../org/traccar/protocol/TranSyncProtocol.java | 22 ++ .../traccar/protocol/TranSyncProtocolDecoder.java | 353 +++++++++++++++++++++ .../protocol/TranSyncProtocolDecoderTest.java | 22 ++ 3 files changed, 397 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/TranSyncProtocol.java create mode 100644 src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocol.java b/src/main/java/org/traccar/protocol/TranSyncProtocol.java new file mode 100644 index 000000000..0634642df --- /dev/null +++ b/src/main/java/org/traccar/protocol/TranSyncProtocol.java @@ -0,0 +1,22 @@ +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 TranSyncProtocol extends BaseProtocol { + + @Inject + public TranSyncProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + 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 new file mode 100644 index 000000000..7cafc09ee --- /dev/null +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -0,0 +1,353 @@ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.UnitsConverter; +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.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class TranSyncProtocolDecoder extends BaseProtocolDecoder { + + public TranSyncProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private boolean isOptionalParameters; + private boolean extended; + private final String STX = "3A3A"; + private final String ETX = "2323"; + private String lac; + private String deviceId; + private Date datePacket; + private double latitude; + private double longitude; + private double speed; + private int course; + private int mobileNetworkCode; + private int gsmSignalStrength; + private double batteryVoltage; + private int satellitesNumber; + private int hdopProtocol; + private short adcVoltageInMilliVolts; + private String rfidTagName; + private int adc2; + private int cellIdInt; + private int lacInt; + private int odometer; + private boolean isGpsFix; + private boolean isLiveData; + private boolean hasGpsAlert; + private boolean isIgnitionOff; + private boolean isPowerOff; + private int deviceAlert; + private String gpsTrackerModel; + private boolean isOutPutTwo; + private boolean isOutPutOne; + private boolean isInPutThree; + + + + public String getLac() { + return lac; + } + + public void setLac(String lac) { + this.lac = lac; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public void setDatePacket(Date datePacket) { + this.datePacket = datePacket; + } + + public double getLatitude() { + return latitude; + } + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + public double getLongitude() { + return longitude; + } + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + public int getCourse() { + return course; + } + + public void setCourse(int course) { + this.course = course; + } + + public void setCellId(String cellId) { + } + + public int getAdc2() { + return adc2; + } + + public void setAdc2(String adc2) { + this.adc2 = Integer.parseInt(adc2); + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public void setTimestampPacket(int year, int month, int day, int hours, int minutes, int seconds) { + + String dataString = ""+year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); + simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + try { + Date deviceTime = simpleDateFormat.parse(dataString); + long timestampPacket = deviceTime.toInstant().toEpochMilli(); + this.setDatePacket(deviceTime); + + } catch (ParseException e) { + e.printStackTrace(); + } + } + + protected void setDeviceAlert(Position position, int alert) { + switch (alert) { + case 10: + position.set(Position.ALARM_SOS, true); + break; + case 11: + position.set(Position.ALARM_SOS, false); + break; + case 16: + position.set(Position.KEY_EVENT, 16); + break; + case 3: + position.set("distressCutOff", true); + break; + case 22: + position.set("tilt", true); + break; + case 9: + position.set(Position.KEY_EVENT, 9); + case 17: + position.set(Position.ALARM_OVERSPEED, true); + break; + case 13: + position.set(Position.ALARM_BRAKING, true); + break; + case 14: + position.set(Position.ALARM_ACCELERATION, true); + break; + case 15: + position.set(Position.KEY_EVENT, 15); + break; + case 23: + position.set(Position.ALARM_ACCIDENT, true); + break; + case 12: + position.set(Position.KEY_EVENT, 12); + break; + case 6: + position.set(Position.ALARM_POWER_RESTORED, true); + break; + case 4: + position.set(Position.ALARM_LOW_BATTERY, true); + break; + case 5: + position.set(Position.KEY_EVENT, 5); + break; + + } + + } + + protected void setInstanceParameters(Object msg) throws Exception { + ByteBuf buf = (ByteBuf) msg; + + if (ByteBufUtil.hexDump(buf, 0, 2).toUpperCase().equals(this.STX)) { + buf.readUnsignedShort(); + } + int packetLength = buf.readByte(); + this.lacInt = buf.readUnsignedShort(); + this.deviceId = ByteBufUtil.hexDump(buf, buf.readerIndex(), 8).toUpperCase().trim().replaceFirst("^0+(?!$)", ""); + buf.readBytes(8); + int informationSerialNumber = buf.readUnsignedShort(); + int protocolNumber = buf.readUnsignedByte(); + // Information Content + int year = buf.readUnsignedByte(); + int month = buf.readUnsignedByte(); + int day = buf.readUnsignedByte(); + int hour = buf.readUnsignedByte(); + int minute = buf.readUnsignedByte(); + int second = buf.readUnsignedByte(); + this.setTimestampPacket(year, month, day, hour, minute, second); + this.latitude = (long) buf.readUnsignedInt() / 1800000.0; + this.longitude = (long) buf.readUnsignedInt() / 1800000.0; + this.speed = UnitsConverter.knotsFromKph(buf.readUnsignedByte()); + this.course = buf.readUnsignedShort(); + this.mobileNetworkCode = buf.readUnsignedByte(); + this.cellIdInt = buf.readUnsignedShort(); + // Status Bytes + int zeroByte = buf.readUnsignedByte(); + this.isOutPutTwo = BitUtil.check(zeroByte, 0); + this.isOutPutOne = BitUtil.check(zeroByte, 1); + this.isInPutThree = BitUtil.check(zeroByte, 2); + this.isPowerOff = BitUtil.check(zeroByte, 3); + this.isIgnitionOff = BitUtil.check(zeroByte, 4); + boolean isgpsFixed = BitUtil.check(zeroByte, 7); + + + this.isGpsFix = BitUtil.check(zeroByte, 0); + int oneByte = buf.readUnsignedByte(); + this.deviceAlert = buf.readUnsignedByte(); + int threeByte = buf.readUnsignedByte(); + this.isLiveData = (threeByte & 0b10000000) == 0; + this.hasGpsAlert = (threeByte & 0b00100000) != 0; + int trackerType = threeByte & 0b00001111; + + switch (trackerType) { + case 1: + this.gpsTrackerModel = "basic"; + break; + case 2: + this.gpsTrackerModel = "asset"; + break; + case 3: + this.gpsTrackerModel = "bike"; + break; + case 4: + this.gpsTrackerModel = "serial"; + break; + case 5: + this.gpsTrackerModel = "obd"; + break; + case 6: + this.gpsTrackerModel = "l1"; + break; + case 7: + this.gpsTrackerModel = "ais"; + break; + default: + this.gpsTrackerModel = "unknown"; + break; + } + // Additional Info + this.gsmSignalStrength = buf.readUnsignedByte(); + this.batteryVoltage = (double) (buf.readUnsignedByte() / 10); + this.satellitesNumber = buf.readUnsignedByte(); + this.hdopProtocol = buf.readUnsignedByte(); + this.adcVoltageInMilliVolts = (short) buf.readUnsignedShort(); + this.isOptionalParameters = (boolean) (buf.readableBytes() > 2); + // Optional parameters + if (this.isOptionalParameters) { // Always True + int odometerIndex = buf.readUnsignedByte(); + int odometerLength = buf.readUnsignedByte(); + if (odometerLength > 0) { + String odometerReading = ByteBufUtil.hexDump(buf, buf.readerIndex(), odometerLength).toUpperCase().trim().replaceFirst("^0+(?!$)", ""); + this.odometer = Integer.parseInt(odometerReading); + buf.readBytes(odometerLength); + } + if ((buf.readableBytes() > 2)) { + int rfidIndex = buf.readUnsignedByte(); + int rfidLength = buf.readUnsignedByte(); + if(rfidLength > 0) { + this.rfidTagName = ByteBufUtil.hexDump(buf, buf.readerIndex(), rfidLength).toUpperCase().trim(); + buf.readBytes(rfidLength); + } + } + if ((buf.readableBytes() > 5)) { + int adcTwoIndex = buf.readUnsignedByte(); + int adcTwoLength = buf.readUnsignedByte(); + if (adcTwoLength > 0){ + this.adc2 = buf.readUnsignedShort(); + } + } + } + + } + + private Position positionHandler(Channel channel, SocketAddress remoteAddress) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, this.deviceId); + if (deviceSession == null) { + return null; + } + Position position = new Position(getProtocolName()); + long devicesessionId = deviceSession.getDeviceId(); + position.setDeviceId(devicesessionId) ; + position.setValid(true); + position.setTime(this.datePacket); + position.setLatitude(this.latitude); + position.setLongitude(this.longitude); + position.setSpeed(this.speed); + position.setCourse(this.course); + position.set("model", this.gpsTrackerModel); + position.set(Position.KEY_HDOP, this.hdopProtocol); + position.set(Position.KEY_BATTERY, this.batteryVoltage); + position.set(Position.KEY_ODOMETER, this.odometer); + position.set(Position.PREFIX_ADC + 1, this.adcVoltageInMilliVolts); + position.set(Position.PREFIX_ADC + 2, this.adc2); + position.set("tag", this.rfidTagName); + position.set(Position.KEY_SATELLITES, this.satellitesNumber); + CellTower cellTower = CellTower.fromLacCid(getConfig(), this.lacInt, this.cellIdInt); + cellTower.setMobileNetworkCode(this.mobileNetworkCode); + cellTower.setSignalStrength(this.gsmSignalStrength); + position.setNetwork(new Network(cellTower)); + if (this.isOutPutOne){ position.set(Position.PREFIX_OUT + 1, this.isOutPutOne);} + if (this.isOutPutTwo){ position.set(Position.PREFIX_OUT + 2, this.isOutPutTwo);} + if (this.isInPutThree){ position.set(Position.PREFIX_IN + 2, this.isInPutThree);} + if (this.isGpsFix) { position.set("gpsFix", this.isGpsFix); } + if (!this.isLiveData) { position.set("restored", true); } + if (this.hasGpsAlert) { + position.set(Position.ALARM_GPS_ANTENNA_CUT, true); + position.set("gpsAlert", true); + } + position.set(Position.KEY_IGNITION, this.isIgnitionOff); + if (isPowerOff){ position.set(Position.ALARM_POWER_OFF, this.isPowerOff );} + position.set(Position.KEY_GPS, true); + if (this.deviceAlert > 0) { setDeviceAlert(position, this.deviceAlert); } + + return position; + } + + @Override + protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + try { + setInstanceParameters(msg); + } + catch (Exception e) { + return null; + } + + return positionHandler(channel, remoteAddress); + } + +} diff --git a/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java new file mode 100644 index 000000000..1b90566d4 --- /dev/null +++ b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java @@ -0,0 +1,22 @@ +package org.traccar.protocol; + + +import org.junit.jupiter.api.Test; +import org.traccar.ProtocolTest; + +public class TranSyncProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new TranSyncProtocolDecoder(null)); + + + verifyPosition(decoder, binary( + "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000000000050252ee060200822323")); + + verifyAttributes(decoder, binary( + "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000000000050252ee060200822323") + ); + } +} -- cgit v1.2.3 From cd092d7e2733881266a3b864743df61e6ac76ce4 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Mon, 15 May 2023 21:55:20 +0300 Subject: Remove Instance variables from TranSyncProtocolDecoder.java Add parseDate function Add getTrackerModel function Add setNetwork function Rename setTimestampPacket function -> getDatefromIntegerParameters --- .../traccar/protocol/TranSyncProtocolDecoder.java | 303 ++++++--------------- 1 file changed, 84 insertions(+), 219 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index 7cafc09ee..d5a69dbe2 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -24,117 +24,18 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private boolean isOptionalParameters; - private boolean extended; - private final String STX = "3A3A"; - private final String ETX = "2323"; - private String lac; - private String deviceId; - private Date datePacket; - private double latitude; - private double longitude; - private double speed; - private int course; - private int mobileNetworkCode; - private int gsmSignalStrength; - private double batteryVoltage; - private int satellitesNumber; - private int hdopProtocol; - private short adcVoltageInMilliVolts; - private String rfidTagName; - private int adc2; - private int cellIdInt; - private int lacInt; - private int odometer; - private boolean isGpsFix; - private boolean isLiveData; - private boolean hasGpsAlert; - private boolean isIgnitionOff; - private boolean isPowerOff; - private int deviceAlert; - private String gpsTrackerModel; - private boolean isOutPutTwo; - private boolean isOutPutOne; - private boolean isInPutThree; - - - - public String getLac() { - return lac; - } - - public void setLac(String lac) { - this.lac = lac; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public void setDatePacket(Date datePacket) { - this.datePacket = datePacket; - } - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - public int getCourse() { - return course; - } - - public void setCourse(int course) { - this.course = course; - } - - public void setCellId(String cellId) { - } - - public int getAdc2() { - return adc2; - } - - public void setAdc2(String adc2) { - this.adc2 = Integer.parseInt(adc2); - } - - public double getSpeed() { - return speed; - } - - public void setSpeed(double speed) { - this.speed = speed; - } - - public void setTimestampPacket(int year, int month, int day, int hours, int minutes, int seconds) { + public Date getDatefromIntegerParameters(int year, int month, int day, int hours, int minutes, int seconds) { String dataString = ""+year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { - Date deviceTime = simpleDateFormat.parse(dataString); - long timestampPacket = deviceTime.toInstant().toEpochMilli(); - this.setDatePacket(deviceTime); + return simpleDateFormat.parse(dataString); } catch (ParseException e) { e.printStackTrace(); } + return null; } protected void setDeviceAlert(Position position, int alert) { @@ -188,166 +89,130 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } - protected void setInstanceParameters(Object msg) throws Exception { - ByteBuf buf = (ByteBuf) msg; + private void setNetwork(Position position, int lacInt, int cellIdInt, int mobileNetworkCode, int gsmSignalStrength){ + CellTower cellTower = CellTower.fromLacCid(getConfig(), lacInt, cellIdInt); + cellTower.setMobileNetworkCode(mobileNetworkCode); + cellTower.setSignalStrength(gsmSignalStrength); + position.setNetwork(new Network(cellTower)); + + } + + private String getTrackerModel(int mask){ + + switch (mask) { + 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"; + default: + return "unknown"; + } + + } - if (ByteBufUtil.hexDump(buf, 0, 2).toUpperCase().equals(this.STX)) { + private Position parseData(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + if (ByteBufUtil.hexDump(buf, 0, 2).equalsIgnoreCase("3A3A")) { buf.readUnsignedShort(); } int packetLength = buf.readByte(); - this.lacInt = buf.readUnsignedShort(); - this.deviceId = ByteBufUtil.hexDump(buf, buf.readerIndex(), 8).toUpperCase().trim().replaceFirst("^0+(?!$)", ""); + int lacInt = buf.readUnsignedShort(); + String deviceId = ByteBufUtil.hexDump(buf, buf.readerIndex(), 8).toUpperCase().trim().replaceFirst("^0+(?!$)", ""); buf.readBytes(8); int informationSerialNumber = buf.readUnsignedShort(); int protocolNumber = buf.readUnsignedByte(); - // Information Content + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + long devicesessionId = deviceSession.getDeviceId(); + + position.setDeviceId(devicesessionId) ; + position.setValid(true); int year = buf.readUnsignedByte(); int month = buf.readUnsignedByte(); int day = buf.readUnsignedByte(); int hour = buf.readUnsignedByte(); int minute = buf.readUnsignedByte(); int second = buf.readUnsignedByte(); - this.setTimestampPacket(year, month, day, hour, minute, second); - this.latitude = (long) buf.readUnsignedInt() / 1800000.0; - this.longitude = (long) buf.readUnsignedInt() / 1800000.0; - this.speed = UnitsConverter.knotsFromKph(buf.readUnsignedByte()); - this.course = buf.readUnsignedShort(); - this.mobileNetworkCode = buf.readUnsignedByte(); - this.cellIdInt = buf.readUnsignedShort(); - // Status Bytes + position.setTime(getDatefromIntegerParameters(year, month, day, hour, minute, second)); + position.setLatitude(buf.readUnsignedInt() / 1800000.0); + position.setLongitude(buf.readUnsignedInt() / 1800000.0); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + position.setCourse(buf.readUnsignedShort()); + int mobileNetworkCode = buf.readUnsignedByte(); + int cellIdInt = buf.readUnsignedShort(); int zeroByte = buf.readUnsignedByte(); - this.isOutPutTwo = BitUtil.check(zeroByte, 0); - this.isOutPutOne = BitUtil.check(zeroByte, 1); - this.isInPutThree = BitUtil.check(zeroByte, 2); - this.isPowerOff = BitUtil.check(zeroByte, 3); - this.isIgnitionOff = BitUtil.check(zeroByte, 4); - boolean isgpsFixed = BitUtil.check(zeroByte, 7); - - - this.isGpsFix = BitUtil.check(zeroByte, 0); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(zeroByte, 0)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(zeroByte, 1)); + position.set(Position.PREFIX_IN + 3, BitUtil.check(zeroByte, 2)); + if (BitUtil.check(zeroByte, 3)) position.set(Position.ALARM_POWER_OFF, true); + position.set(Position.KEY_IGNITION, BitUtil.check(zeroByte, 4)); + position.set("gpsFix", BitUtil.check(zeroByte, 7)); int oneByte = buf.readUnsignedByte(); - this.deviceAlert = buf.readUnsignedByte(); + int deviceAlert = buf.readUnsignedByte(); + if (deviceAlert > 0) { setDeviceAlert(position, deviceAlert); } int threeByte = buf.readUnsignedByte(); - this.isLiveData = (threeByte & 0b10000000) == 0; - this.hasGpsAlert = (threeByte & 0b00100000) != 0; - int trackerType = threeByte & 0b00001111; - - switch (trackerType) { - case 1: - this.gpsTrackerModel = "basic"; - break; - case 2: - this.gpsTrackerModel = "asset"; - break; - case 3: - this.gpsTrackerModel = "bike"; - break; - case 4: - this.gpsTrackerModel = "serial"; - break; - case 5: - this.gpsTrackerModel = "obd"; - break; - case 6: - this.gpsTrackerModel = "l1"; - break; - case 7: - this.gpsTrackerModel = "ais"; - break; - default: - this.gpsTrackerModel = "unknown"; - break; + if (!((threeByte & 0b10000000) == 0)) position.set("restored", true); + if ((threeByte & 0b00100000) != 0) { + position.set(Position.ALARM_GPS_ANTENNA_CUT, true); + position.set("gpsAlert", true); } - // Additional Info - this.gsmSignalStrength = buf.readUnsignedByte(); - this.batteryVoltage = (double) (buf.readUnsignedByte() / 10); - this.satellitesNumber = buf.readUnsignedByte(); - this.hdopProtocol = buf.readUnsignedByte(); - this.adcVoltageInMilliVolts = (short) buf.readUnsignedShort(); - this.isOptionalParameters = (boolean) (buf.readableBytes() > 2); - // Optional parameters - if (this.isOptionalParameters) { // Always True + position.set("model", getTrackerModel(threeByte & 0b00001111)); + int gsmSignalStrength = buf.readUnsignedByte(); + 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()); + boolean isOptionalParameters = (buf.readableBytes() > 2); + setNetwork(position, lacInt, cellIdInt, mobileNetworkCode, gsmSignalStrength); + if (isOptionalParameters) { // Always True int odometerIndex = buf.readUnsignedByte(); int odometerLength = buf.readUnsignedByte(); if (odometerLength > 0) { String odometerReading = ByteBufUtil.hexDump(buf, buf.readerIndex(), odometerLength).toUpperCase().trim().replaceFirst("^0+(?!$)", ""); - this.odometer = Integer.parseInt(odometerReading); + int odometer = Integer.parseInt(odometerReading); buf.readBytes(odometerLength); + position.set(Position.KEY_ODOMETER, odometer); } if ((buf.readableBytes() > 2)) { int rfidIndex = buf.readUnsignedByte(); int rfidLength = buf.readUnsignedByte(); if(rfidLength > 0) { - this.rfidTagName = ByteBufUtil.hexDump(buf, buf.readerIndex(), rfidLength).toUpperCase().trim(); + String rfidTagName = ByteBufUtil.hexDump(buf, buf.readerIndex(), rfidLength).toUpperCase().trim(); buf.readBytes(rfidLength); + position.set("tag", rfidTagName); } } if ((buf.readableBytes() > 5)) { int adcTwoIndex = buf.readUnsignedByte(); int adcTwoLength = buf.readUnsignedByte(); if (adcTwoLength > 0){ - this.adc2 = buf.readUnsignedShort(); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); } } } - } - - private Position positionHandler(Channel channel, SocketAddress remoteAddress) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, this.deviceId); - if (deviceSession == null) { - return null; - } - Position position = new Position(getProtocolName()); - long devicesessionId = deviceSession.getDeviceId(); - position.setDeviceId(devicesessionId) ; - position.setValid(true); - position.setTime(this.datePacket); - position.setLatitude(this.latitude); - position.setLongitude(this.longitude); - position.setSpeed(this.speed); - position.setCourse(this.course); - position.set("model", this.gpsTrackerModel); - position.set(Position.KEY_HDOP, this.hdopProtocol); - position.set(Position.KEY_BATTERY, this.batteryVoltage); - position.set(Position.KEY_ODOMETER, this.odometer); - position.set(Position.PREFIX_ADC + 1, this.adcVoltageInMilliVolts); - position.set(Position.PREFIX_ADC + 2, this.adc2); - position.set("tag", this.rfidTagName); - position.set(Position.KEY_SATELLITES, this.satellitesNumber); - CellTower cellTower = CellTower.fromLacCid(getConfig(), this.lacInt, this.cellIdInt); - cellTower.setMobileNetworkCode(this.mobileNetworkCode); - cellTower.setSignalStrength(this.gsmSignalStrength); - position.setNetwork(new Network(cellTower)); - if (this.isOutPutOne){ position.set(Position.PREFIX_OUT + 1, this.isOutPutOne);} - if (this.isOutPutTwo){ position.set(Position.PREFIX_OUT + 2, this.isOutPutTwo);} - if (this.isInPutThree){ position.set(Position.PREFIX_IN + 2, this.isInPutThree);} - if (this.isGpsFix) { position.set("gpsFix", this.isGpsFix); } - if (!this.isLiveData) { position.set("restored", true); } - if (this.hasGpsAlert) { - position.set(Position.ALARM_GPS_ANTENNA_CUT, true); - position.set("gpsAlert", true); - } - position.set(Position.KEY_IGNITION, this.isIgnitionOff); - if (isPowerOff){ position.set(Position.ALARM_POWER_OFF, this.isPowerOff );} - position.set(Position.KEY_GPS, true); - if (this.deviceAlert > 0) { setDeviceAlert(position, this.deviceAlert); } - return position; } @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - try { - setInstanceParameters(msg); - } - catch (Exception e) { - return null; - } - - return positionHandler(channel, remoteAddress); + ByteBuf buffer = (ByteBuf) msg; + return parseData(channel, remoteAddress, buffer); } } -- cgit v1.2.3 From e44e9f860b11a50b3e39e3895ea9ea5624282b78 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 15 May 2023 12:06:14 -0700 Subject: Add HTML branding overrides --- src/main/java/org/traccar/api/MediaFilter.java | 11 +-- src/main/java/org/traccar/model/ExtendedModel.java | 8 ++- .../java/org/traccar/web/CharResponseWrapper.java | 82 ++++++++++++++++++++++ src/main/java/org/traccar/web/OverrideFilter.java | 71 +++++++++++++++++++ src/main/java/org/traccar/web/WebModule.java | 4 +- 5 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/traccar/web/CharResponseWrapper.java create mode 100644 src/main/java/org/traccar/web/OverrideFilter.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index ab75bdc5d..e6556189a 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.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"); @@ -32,7 +32,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import javax.servlet.Filter; import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -57,10 +56,6 @@ public class MediaFilter implements Filter { this.permissionsServiceProvider = permissionsServiceProvider; } - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -99,8 +94,4 @@ public class MediaFilter implements Filter { } } - @Override - public void destroy() { - } - } diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 7a61eda8c..6a4f502f7 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -89,14 +89,18 @@ public class ExtendedModel extends BaseModel { } } - public String getString(String key) { + public String getString(String key, String defaultValue) { if (attributes.containsKey(key)) { return attributes.get(key).toString(); } else { - return null; + return defaultValue; } } + public String getString(String key) { + return getString(key, null); + } + public double getDouble(String key) { if (attributes.containsKey(key)) { Object value = attributes.get(key); diff --git a/src/main/java/org/traccar/web/CharResponseWrapper.java b/src/main/java/org/traccar/web/CharResponseWrapper.java new file mode 100644 index 000000000..0e7976ce0 --- /dev/null +++ b/src/main/java/org/traccar/web/CharResponseWrapper.java @@ -0,0 +1,82 @@ +/* + * 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.web; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class CharResponseWrapper extends HttpServletResponseWrapper { + + private final ByteArrayOutputStream capture; + private ServletOutputStream output; + + public CharResponseWrapper(HttpServletResponse response) { + super(response); + capture = new ByteArrayOutputStream(response.getBufferSize()); + } + + @Override + public ServletOutputStream getOutputStream() { + if (output == null) { + output = new ServletOutputStream() { + @Override + public boolean isReady() { + return true; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + } + + @Override + public void write(int b) { + capture.write(b); + } + + @Override + public void flush() throws IOException { + capture.flush(); + } + + @Override + public void close() throws IOException { + capture.close(); + } + }; + } + return output; + } + + @Override + public void flushBuffer() throws IOException { + super.flushBuffer(); + if (output != null) { + output.flush(); + } + } + + public String getCaptureAsString() throws IOException { + if (output != null) { + output.close(); + } + return capture.toString(getCharacterEncoding()); + } + +} diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java new file mode 100644 index 000000000..cb69dfbfa --- /dev/null +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -0,0 +1,71 @@ +/* + * 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.web; + +import com.google.inject.Provider; +import org.traccar.api.security.PermissionsService; +import org.traccar.model.Server; +import org.traccar.storage.StorageException; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Singleton +public class OverrideFilter implements Filter { + + private final Provider permissionsServiceProvider; + + @Inject + public OverrideFilter(Provider permissionsServiceProvider) { + this.permissionsServiceProvider = permissionsServiceProvider; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response); + + chain.doFilter(request, wrapper); + + Server server; + try { + server = permissionsServiceProvider.get().getServer(); + } catch (StorageException e) { + throw new RuntimeException(e); + } + + String title = server.getString("serverTitle", "Traccar"); + String description = server.getString("serverDescription", "Traccar GPS Tracking System"); + String colorPrimary = server.getString("serverColorPrimary", "#1a237e"); + + String alteredContent = wrapper.getCaptureAsString() + .replace("${title}", title) + .replace("${description}", description) + .replace("${colorPrimary}", colorPrimary); + + response.setContentLength(alteredContent.length()); + response.getWriter().write(alteredContent); + } + +} diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java index 0722c5d1e..f06abf0b5 100644 --- a/src/main/java/org/traccar/web/WebModule.java +++ b/src/main/java/org/traccar/web/WebModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -23,6 +23,8 @@ public class WebModule extends ServletModule { @Override protected void configureServlets() { + filter("/").through(OverrideFilter.class); + filter("/manifest.json").through(OverrideFilter.class); filter("/api/*").through(ThrottlingFilter.class); filter("/api/media/*").through(MediaFilter.class); serve("/api/socket").with(AsyncSocketServlet.class); -- cgit v1.2.3 From 599abc3523b93f83281d44b109676b1b0ed602f5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 15 May 2023 12:50:11 -0700 Subject: Rename server attributes --- src/main/java/org/traccar/web/OverrideFilter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java index cb69dfbfa..303c21253 100644 --- a/src/main/java/org/traccar/web/OverrideFilter.java +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -55,9 +55,9 @@ public class OverrideFilter implements Filter { throw new RuntimeException(e); } - String title = server.getString("serverTitle", "Traccar"); - String description = server.getString("serverDescription", "Traccar GPS Tracking System"); - String colorPrimary = server.getString("serverColorPrimary", "#1a237e"); + String title = server.getString("title", "Traccar"); + String description = server.getString("description", "Traccar GPS Tracking System"); + String colorPrimary = server.getString("colorPrimary", "#1a237e"); String alteredContent = wrapper.getCaptureAsString() .replace("${title}", title) -- cgit v1.2.3 From d5717272c664b6e09408f31a8448c80a0f380ddb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 15 May 2023 15:41:55 -0700 Subject: Handle modern paths --- .../java/org/traccar/web/CharResponseWrapper.java | 4 +- .../java/org/traccar/web/ModernDefaultServlet.java | 33 +++++++++++++++++ src/main/java/org/traccar/web/OverrideFilter.java | 43 +++++++++++++--------- src/main/java/org/traccar/web/WebModule.java | 3 +- src/main/java/org/traccar/web/WebServer.java | 12 ++---- 5 files changed, 65 insertions(+), 30 deletions(-) create mode 100644 src/main/java/org/traccar/web/ModernDefaultServlet.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/CharResponseWrapper.java b/src/main/java/org/traccar/web/CharResponseWrapper.java index 0e7976ce0..477fe7928 100644 --- a/src/main/java/org/traccar/web/CharResponseWrapper.java +++ b/src/main/java/org/traccar/web/CharResponseWrapper.java @@ -72,11 +72,11 @@ public class CharResponseWrapper extends HttpServletResponseWrapper { } } - public String getCaptureAsString() throws IOException { + public byte[] getCapture() throws IOException { if (output != null) { output.close(); } - return capture.toString(getCharacterEncoding()); + return capture.toByteArray(); } } diff --git a/src/main/java/org/traccar/web/ModernDefaultServlet.java b/src/main/java/org/traccar/web/ModernDefaultServlet.java new file mode 100644 index 000000000..bae089d6c --- /dev/null +++ b/src/main/java/org/traccar/web/ModernDefaultServlet.java @@ -0,0 +1,33 @@ +/* + * 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.web; + +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.util.resource.Resource; + +public class ModernDefaultServlet extends DefaultServlet { + + @Override + public Resource getResource(String pathInContext) { + return super.getResource(pathInContext.indexOf('.') < 0 ? "/" : pathInContext); + } + + @Override + public String getWelcomeFile(String pathInContext) { + return super.getWelcomeFile("/"); + } + +} diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java index 303c21253..708632bc1 100644 --- a/src/main/java/org/traccar/web/OverrideFilter.java +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -27,6 +27,7 @@ import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -44,28 +45,36 @@ public class OverrideFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response); + CharResponseWrapper wrappedResponse = new CharResponseWrapper((HttpServletResponse) response); - chain.doFilter(request, wrapper); + chain.doFilter(request, wrappedResponse); - Server server; - try { - server = permissionsServiceProvider.get().getServer(); - } catch (StorageException e) { - throw new RuntimeException(e); - } + byte[] bytes = wrappedResponse.getCapture(); + if (wrappedResponse.getContentType().contains("text/html") + || ((HttpServletRequest) request).getPathInfo().endsWith("manifest.json")) { + + Server server; + try { + server = permissionsServiceProvider.get().getServer(); + } catch (StorageException e) { + throw new RuntimeException(e); + } - String title = server.getString("title", "Traccar"); - String description = server.getString("description", "Traccar GPS Tracking System"); - String colorPrimary = server.getString("colorPrimary", "#1a237e"); + String title = server.getString("title", "Traccar"); + String description = server.getString("description", "Traccar GPS Tracking System"); + String colorPrimary = server.getString("colorPrimary", "#1a237e"); - String alteredContent = wrapper.getCaptureAsString() - .replace("${title}", title) - .replace("${description}", description) - .replace("${colorPrimary}", colorPrimary); + String alteredContent = new String(wrappedResponse.getCapture()) + .replace("${title}", title) + .replace("${description}", description) + .replace("${colorPrimary}", colorPrimary); - response.setContentLength(alteredContent.length()); - response.getWriter().write(alteredContent); + response.setContentLength(alteredContent.length()); + response.getOutputStream().write(alteredContent.getBytes()); + + } else { + response.getOutputStream().write(bytes); + } } } diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java index f06abf0b5..a32a6f447 100644 --- a/src/main/java/org/traccar/web/WebModule.java +++ b/src/main/java/org/traccar/web/WebModule.java @@ -23,8 +23,7 @@ public class WebModule extends ServletModule { @Override protected void configureServlets() { - filter("/").through(OverrideFilter.class); - filter("/manifest.json").through(OverrideFilter.class); + filter("/*").through(OverrideFilter.class); filter("/api/*").through(ThrottlingFilter.class); filter("/api/media/*").through(MediaFilter.class); serve("/api/socket").with(AsyncSocketServlet.class); diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 79d19cc9b..29e6de9f2 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -103,14 +103,8 @@ public class WebServer implements LifecycleObject { @Override protected void handleErrorPage( HttpServletRequest request, Writer writer, int code, String message) throws IOException { - Path index = Paths.get(config.getString(Keys.WEB_PATH), "index.html"); - if (code == HttpStatus.NOT_FOUND_404 - && !request.getPathInfo().startsWith("/api/") && Files.exists(index)) { - writer.write(Files.readString(index)); - } else { - writer.write("Error" - + code + " - " + HttpStatus.getMessage(code) + ""); - } + writer.write("Error" + + code + " - " + HttpStatus.getMessage(code) + ""); } }); @@ -150,7 +144,7 @@ public class WebServer implements LifecycleObject { } private void initWebApp(ServletContextHandler servletHandler) { - ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); + ServletHolder servletHolder = new ServletHolder(ModernDefaultServlet.class); servletHolder.setInitParameter("resourceBase", new File(config.getString(Keys.WEB_PATH)).getAbsolutePath()); servletHolder.setInitParameter("dirAllowed", "false"); if (config.getBoolean(Keys.WEB_DEBUG)) { -- cgit v1.2.3 From f7382adfc212750d8863bb93d84317294cdf0da8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 15 May 2023 15:44:25 -0700 Subject: Remove unused imports --- src/main/java/org/traccar/web/WebServer.java | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 29e6de9f2..ce1220157 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -62,9 +62,6 @@ import java.io.File; import java.io.IOException; import java.io.Writer; import java.net.InetSocketAddress; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.EnumSet; public class WebServer implements LifecycleObject { -- cgit v1.2.3 From 30f09160d226fbe0133f96cdbf6f25c72e191a06 Mon Sep 17 00:00:00 2001 From: K-J-Dod24 Date: Tue, 16 May 2023 08:48:19 +0100 Subject: removed Engine temp (115) --- src/main/java/org/traccar/model/Position.java | 1 - src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 1 - 2 files changed, 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index c48e34e03..3ed340703 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -81,7 +81,6 @@ public class Position extends Message { public static final String KEY_ACCELERATION = "acceleration"; public static final String KEY_DEVICE_TEMP = "deviceTemp"; // celsius public static final String KEY_COOLANT_TEMP = "coolantTemp"; // celsius - public static final String KEY_ENGINE_TEMP = "engineTemp"; // celsius public static final String KEY_ENGINE_LOAD = "engineLoad"; public static final String KEY_OPERATOR = "operator"; public static final String KEY_COMMAND = "command"; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index d60107d7a..2f378f30a 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -248,7 +248,6 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { }); register(80, fmbXXX, (p, b) -> p.set("dataMode", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); - register(115, fmbXXX, (p, b) -> p.set(Position.KEY_ENGINE_TEMP, b.readShort() * 0.1)); register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); register(181, null, (p, b) -> p.set(Position.KEY_PDOP, b.readUnsignedShort() * 0.1)); -- cgit v1.2.3 From 8ee05feeafbf7c6356e1afd65e140823c717aef8 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Tue, 16 May 2023 16:32:54 +0300 Subject: Reafactoring --- .../traccar/protocol/TranSyncProtocolDecoder.java | 216 +++++++++------------ .../protocol/TranSyncProtocolDecoderTest.java | 7 +- 2 files changed, 98 insertions(+), 125 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index d5a69dbe2..d07b70365 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -1,3 +1,18 @@ +/* + * Copyright 2013 - 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; @@ -6,6 +21,7 @@ import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -13,206 +29,166 @@ import org.traccar.model.Position; import org.traccar.session.DeviceSession; import java.net.SocketAddress; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; +import java.util.Arrays; public class TranSyncProtocolDecoder extends BaseProtocolDecoder { + private static final byte[] STX = new byte[]{0x3a, 0x3a}; + public TranSyncProtocolDecoder(Protocol protocol) { super(protocol); } - public Date getDatefromIntegerParameters(int year, int month, int day, int hours, int minutes, int seconds) { - - String dataString = ""+year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); - simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - try { - return simpleDateFormat.parse(dataString); - - } catch (ParseException e) { - e.printStackTrace(); - } - return null; - } - - protected void setDeviceAlert(Position position, int alert) { - switch (alert) { + protected void decodeAlarm(Position position, int value) { + switch (value) { case 10: - position.set(Position.ALARM_SOS, true); + position.set(Position.KEY_ALARM, Position.ALARM_SOS); break; case 11: - position.set(Position.ALARM_SOS, false); + position.set(Position.KEY_EVENT, 11); break; case 16: position.set(Position.KEY_EVENT, 16); break; case 3: - position.set("distressCutOff", true); + position.set(Position.KEY_ALARM, 3); break; case 22: - position.set("tilt", true); + position.set(Position.KEY_ALARM, 22); break; case 9: position.set(Position.KEY_EVENT, 9); case 17: - position.set(Position.ALARM_OVERSPEED, true); + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); break; case 13: - position.set(Position.ALARM_BRAKING, true); + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); break; case 14: - position.set(Position.ALARM_ACCELERATION, true); + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); break; case 15: position.set(Position.KEY_EVENT, 15); break; case 23: - position.set(Position.ALARM_ACCIDENT, true); + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); break; case 12: position.set(Position.KEY_EVENT, 12); break; case 6: - position.set(Position.ALARM_POWER_RESTORED, true); + position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); break; case 4: - position.set(Position.ALARM_LOW_BATTERY, true); + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); break; case 5: position.set(Position.KEY_EVENT, 5); break; - } - - } - - private void setNetwork(Position position, int lacInt, int cellIdInt, int mobileNetworkCode, int gsmSignalStrength){ - CellTower cellTower = CellTower.fromLacCid(getConfig(), lacInt, cellIdInt); - cellTower.setMobileNetworkCode(mobileNetworkCode); - cellTower.setSignalStrength(gsmSignalStrength); - position.setNetwork(new Network(cellTower)); - } - private String getTrackerModel(int mask){ + private void decodePowerEngineParameters(Position position, int value){ - switch (mask) { - case 1: - return "basic"; - case 2: - return "asset"; - case 3: - return "bike"; + 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)); - case 4: - return "serial"; + } - case 5: - return "obd"; - case 6: - return "l1"; - case 7: - return "ais"; - default: - return "unknown"; + private void decodeTrackerStatusParameters(Position position, int value){ + if (BitUtil.check(value, 7)) position.set("restored", true); + if (BitUtil.check(value, 5)) { + position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); } - } - private Position parseData(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - if (ByteBufUtil.hexDump(buf, 0, 2).equalsIgnoreCase("3A3A")) { + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ByteBuf buf = (ByteBuf) msg; + if (Arrays.equals(ByteBufUtil.getBytes(buf, 0, 2), STX)) { buf.readUnsignedShort(); } - int packetLength = buf.readByte(); - int lacInt = buf.readUnsignedShort(); - String deviceId = ByteBufUtil.hexDump(buf, buf.readerIndex(), 8).toUpperCase().trim().replaceFirst("^0+(?!$)", ""); - buf.readBytes(8); - int informationSerialNumber = buf.readUnsignedShort(); - int protocolNumber = buf.readUnsignedByte(); + buf.readByte(); //packetLength + + int locationAreaCode = buf.readUnsignedShort(); + String deviceId = ByteBufUtil.hexDump(buf.readSlice(8)); + + buf.readUnsignedShort(); //informationSerialNumber + buf.readUnsignedByte(); //protocolNumber + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId); if (deviceSession == null) { return null; } - Position position = new Position(getProtocolName()); - long devicesessionId = deviceSession.getDeviceId(); - - position.setDeviceId(devicesessionId) ; + position.setDeviceId(deviceSession.getDeviceId()); position.setValid(true); - int year = buf.readUnsignedByte(); - int month = buf.readUnsignedByte(); - int day = buf.readUnsignedByte(); - int hour = buf.readUnsignedByte(); - int minute = buf.readUnsignedByte(); - int second = buf.readUnsignedByte(); - position.setTime(getDatefromIntegerParameters(year, month, day, hour, minute, second)); + 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); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); position.setCourse(buf.readUnsignedShort()); + int mobileNetworkCode = buf.readUnsignedByte(); - int cellIdInt = buf.readUnsignedShort(); - int zeroByte = buf.readUnsignedByte(); - position.set(Position.PREFIX_OUT + 1, BitUtil.check(zeroByte, 0)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(zeroByte, 1)); - position.set(Position.PREFIX_IN + 3, BitUtil.check(zeroByte, 2)); - if (BitUtil.check(zeroByte, 3)) position.set(Position.ALARM_POWER_OFF, true); - position.set(Position.KEY_IGNITION, BitUtil.check(zeroByte, 4)); - position.set("gpsFix", BitUtil.check(zeroByte, 7)); - int oneByte = buf.readUnsignedByte(); - int deviceAlert = buf.readUnsignedByte(); - if (deviceAlert > 0) { setDeviceAlert(position, deviceAlert); } - int threeByte = buf.readUnsignedByte(); - if (!((threeByte & 0b10000000) == 0)) position.set("restored", true); - if ((threeByte & 0b00100000) != 0) { - position.set(Position.ALARM_GPS_ANTENNA_CUT, true); - position.set("gpsAlert", true); - } - position.set("model", getTrackerModel(threeByte & 0b00001111)); + int cellTowerId = buf.readUnsignedShort(); + + decodePowerEngineParameters(position, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // not in use + + decodeAlarm(position, buf.readUnsignedByte()); + + decodeTrackerStatusParameters(position, buf.readUnsignedByte()); + int gsmSignalStrength = buf.readUnsignedByte(); + 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()); - boolean isOptionalParameters = (buf.readableBytes() > 2); - setNetwork(position, lacInt, cellIdInt, mobileNetworkCode, gsmSignalStrength); - if (isOptionalParameters) { // Always True - int odometerIndex = buf.readUnsignedByte(); + + CellTower cellTower = CellTower.fromLacCid(getConfig(), locationAreaCode, cellTowerId); + cellTower.setMobileNetworkCode(mobileNetworkCode); + cellTower.setSignalStrength(gsmSignalStrength); + + position.setNetwork(new Network(cellTower)); + + if (buf.readableBytes() > 2) { + buf.readUnsignedByte(); // odometerIndex int odometerLength = buf.readUnsignedByte(); if (odometerLength > 0) { - String odometerReading = ByteBufUtil.hexDump(buf, buf.readerIndex(), odometerLength).toUpperCase().trim().replaceFirst("^0+(?!$)", ""); - int odometer = Integer.parseInt(odometerReading); - buf.readBytes(odometerLength); + int odometer = buf.readBytes(odometerLength).readInt(); position.set(Position.KEY_ODOMETER, odometer); } if ((buf.readableBytes() > 2)) { - int rfidIndex = buf.readUnsignedByte(); - int rfidLength = buf.readUnsignedByte(); - if(rfidLength > 0) { - String rfidTagName = ByteBufUtil.hexDump(buf, buf.readerIndex(), rfidLength).toUpperCase().trim(); - buf.readBytes(rfidLength); - position.set("tag", rfidTagName); + buf.readUnsignedByte(); // tagIndex + int tagLength = buf.readUnsignedByte(); + if (tagLength > 0) { + position.set("tag", ByteBufUtil.hexDump(buf.readSlice(tagLength))); } } if ((buf.readableBytes() > 5)) { - int adcTwoIndex = buf.readUnsignedByte(); - int adcTwoLength = buf.readUnsignedByte(); - if (adcTwoLength > 0){ + buf.readUnsignedByte(); // adc2Index + int adc2Length = buf.readUnsignedByte(); + if (adc2Length > 0) { position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); } } + if ((buf.readableBytes() > 5)) { + buf.readUnsignedByte(); // adc2Index + int adc2Length = buf.readUnsignedByte(); + if (adc2Length > 0 && adc2Length <= buf.readableBytes() - 2) { + position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort()); + } + } } - return position; } - - @Override - protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ByteBuf buffer = (ByteBuf) msg; - return parseData(channel, remoteAddress, buffer); - } - } diff --git a/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java index 1b90566d4..6cf2d0c1f 100644 --- a/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java @@ -1,6 +1,5 @@ package org.traccar.protocol; - import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; @@ -11,12 +10,10 @@ public class TranSyncProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TranSyncProtocolDecoder(null)); - verifyPosition(decoder, binary( - "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000000000050252ee060200822323")); + "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000100000050252ee060200822323")); verifyAttributes(decoder, binary( - "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000000000050252ee060200822323") - ); + "3a3a2b583f086065705154043900801017050b11190f01623ef40887dff00000c25e9ff707000007152a2d0000000105004794916902050000000000050252ee060200822323")); } } -- cgit v1.2.3 From b2e889abf0850aa568353f923a3b3f35008a063e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 May 2023 09:27:41 -0700 Subject: Decode VL502 DTCs --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 10 ++++++++-- .../java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 4beee7696..d3c312f7e 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -41,6 +41,7 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; +import java.util.stream.Collectors; public class HuabaoProtocolDecoder extends BaseProtocolDecoder { @@ -919,14 +920,19 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.setTime(time); break; case 0x02: - count = buf.readUnsignedByte(); + List codes = new LinkedList<>(); + count = buf.readUnsignedShort(); for (int i = 0; i < count; i++) { buf.readUnsignedInt(); // system id int codeCount = buf.readUnsignedShort(); for (int j = 0; j < codeCount; j++) { - buf.skipBytes(16); // code + buf.readUnsignedInt(); // dtc + buf.readUnsignedInt(); // status + codes.add(buf.readCharSequence( + buf.readUnsignedShort(), StandardCharsets.US_ASCII).toString().trim()); } } + position.set(Position.KEY_DTCS, String.join(" ", codes)); getLastLocation(position, time); decodeCoordinates(position, buf); position.setTime(time); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 2f317d049..5fd9ed894 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( + "7e090000344f07788ef87d0138f02305151230460102020001ffffffff000100001457000000020006503134353700000c000a029dc63004b99a98230515132726787e"), + Position.KEY_DTCS, "P1457"); + verifyAttribute(decoder, binary( "7e0200006476806111898300710000000000100046005d3156065f7128000000000000230511165956660b01fe000001031a5d1a8101670831333231343332326902018b6a01166b01006c0f323034303830393230373533363735711438393434343738383030303030323131303030464b7e"), Position.KEY_BATTERY, 3.95); -- cgit v1.2.3 From fbd3ee0d77673d94766a87aa67c05885e44aa7e5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 May 2023 09:28:30 -0700 Subject: Remove unused import --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index d3c312f7e..ee5ab19d6 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -41,7 +41,6 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; -import java.util.stream.Collectors; public class HuabaoProtocolDecoder extends BaseProtocolDecoder { -- cgit v1.2.3 From 7e403cf979d3c01acb5b3dfe0ee37dfa83cba4ff Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Wed, 17 May 2023 11:00:43 +0300 Subject: Add LengthFieldBasedFrameDecoder to TranSyncProtocol --- .../java/org/traccar/protocol/TranSyncProtocol.java | 19 ++++++++++++++++++- .../org/traccar/protocol/TranSyncProtocolDecoder.java | 15 +++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocol.java b/src/main/java/org/traccar/protocol/TranSyncProtocol.java index 0634642df..39db67585 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocol.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocol.java @@ -1,5 +1,22 @@ +/* + * Copyright 2013 - 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 io.netty.handler.codec.LineBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; @@ -14,9 +31,9 @@ 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 TranSyncProtocolDecoder(TranSyncProtocol.this)); } }); } - } diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index d07b70365..bb8c9bbf9 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -17,8 +17,10 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +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; @@ -106,6 +108,18 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } } + private void sendResponse(Channel channel) { + if (channel != null) { + ByteBuf response = Unpooled.buffer(5); + response.writeByte(22); + response.writeByte(1); + response.writeShort(response.capacity()); // length + response.writeByte(4); + + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + } + @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; @@ -189,6 +203,7 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } } } + sendResponse(channel); return position; } } -- cgit v1.2.3 From 9fa4b44281e96ab56f3a0d27745d89265ea417fd Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Wed, 17 May 2023 11:13:43 +0300 Subject: Remove sendResponse function from TranSyncProtocolDecoder.java --- .../java/org/traccar/protocol/TranSyncProtocolDecoder.java | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index bb8c9bbf9..e9247ddf8 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -108,18 +108,6 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } } - private void sendResponse(Channel channel) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(5); - response.writeByte(22); - response.writeByte(1); - response.writeShort(response.capacity()); // length - response.writeByte(4); - - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; @@ -203,7 +191,6 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } } } - sendResponse(channel); return position; } } -- cgit v1.2.3 From b7d46d78adc763eea3aae838f4e056e12e2dc487 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Wed, 17 May 2023 11:43:53 +0300 Subject: Add Position.KEY_ARCHIVE position parameter in decodeTrackerStatusParameters in TranSyncProtocol Add Position.KEY_VERSION_HW position parameter in decodeTrackerStatusParameters in TranSyncProtocol --- .../org/traccar/protocol/TranSyncProtocol.java | 3 +-- .../traccar/protocol/TranSyncProtocolDecoder.java | 29 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocol.java b/src/main/java/org/traccar/protocol/TranSyncProtocol.java index 39db67585..3abe05de8 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocol.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocol.java @@ -16,7 +16,6 @@ package org.traccar.protocol; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; -import io.netty.handler.codec.LineBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; @@ -36,4 +35,4 @@ public class TranSyncProtocol extends BaseProtocol { } }); } -} +} \ No newline at end of file diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index e9247ddf8..759c012b8 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -17,10 +17,8 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; -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; @@ -37,6 +35,28 @@ 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); } @@ -102,10 +122,11 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } private void decodeTrackerStatusParameters(Position position, int value){ - if (BitUtil.check(value, 7)) position.set("restored", true); + 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); } + position.set(Position.KEY_VERSION_HW, getHardwareType(BitUtil.between(value, 0, 3))); } @Override @@ -143,7 +164,7 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { decodePowerEngineParameters(position, buf.readUnsignedByte()); - buf.readUnsignedByte(); // not in use + buf.readUnsignedByte(); // reserved decodeAlarm(position, buf.readUnsignedByte()); -- cgit v1.2.3 From 34f6dfbf1d2c48ae932fa7565dd30d2817d2c1f9 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Wed, 17 May 2023 12:10:17 +0300 Subject: remove extra empty lines --- src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java | 8 +++++--- .../java/org/traccar/protocol/TranSyncProtocolDecoderTest.java | 6 ++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index 759c012b8..acb46ec48 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -131,7 +131,9 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ByteBuf buf = (ByteBuf) msg; + if (Arrays.equals(ByteBufUtil.getBytes(buf, 0, 2), STX)) { buf.readUnsignedShort(); } @@ -183,14 +185,14 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(new Network(cellTower)); - if (buf.readableBytes() > 2) { + 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); } - if ((buf.readableBytes() > 2)) { + if ((buf.readableBytes() > 5)) { buf.readUnsignedByte(); // tagIndex int tagLength = buf.readUnsignedByte(); if (tagLength > 0) { @@ -205,7 +207,7 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } } if ((buf.readableBytes() > 5)) { - buf.readUnsignedByte(); // adc2Index + buf.readUnsignedByte(); // adc3Index int adc2Length = buf.readUnsignedByte(); if (adc2Length > 0 && adc2Length <= buf.readableBytes() - 2) { position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort()); diff --git a/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java index 6cf2d0c1f..c84ae2e0f 100644 --- a/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TranSyncProtocolDecoderTest.java @@ -10,10 +10,8 @@ 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 074dc016d21f9848140d125c2812d8abf25e8d53 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Wed, 17 May 2023 20:29:37 +0300 Subject: Fix Pythonic ussues --- src/main/java/org/traccar/protocol/TranSyncProtocol.java | 2 +- .../org/traccar/protocol/TranSyncProtocolDecoder.java | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocol.java b/src/main/java/org/traccar/protocol/TranSyncProtocol.java index 3abe05de8..5422380b6 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocol.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocol.java @@ -35,4 +35,4 @@ public class TranSyncProtocol extends BaseProtocol { } }); } -} \ No newline at end of file +} diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index acb46ec48..1b7c9539c 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -35,7 +35,7 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { private static final byte[] STX = new byte[]{0x3a, 0x3a}; - private String getHardwareType(int type){ + private String getHardwareType(int type) { switch (type) { case 1: @@ -107,22 +107,28 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { case 5: position.set(Position.KEY_EVENT, 5); break; + default: + position.set(Position.KEY_EVENT, "unknown"); } } - private void decodePowerEngineParameters(Position position, int value){ + 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); + 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); + 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); } -- cgit v1.2.3 From 05a73b06f94e451239ebc61ebb2b8528705bbc61 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Thu, 18 May 2023 12:47:40 +0300 Subject: Fix Latitude/Longitude Formats for negative support Add analizeNegativePosition function in TranSyncProtocolDecoder.java Add statusParameters variable for byte --- .../java/org/traccar/protocol/TranSyncProtocolDecoder.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index 1b7c9539c..130c916b1 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -111,6 +111,15 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { 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) { @@ -122,7 +131,6 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } position.set(Position.KEY_IGNITION, BitUtil.check(value, 3)); position.set("gpsFix", BitUtil.check(value, 0)); - } private void decodeTrackerStatusParameters(Position position, int value) { @@ -169,8 +177,10 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { int mobileNetworkCode = buf.readUnsignedByte(); int cellTowerId = buf.readUnsignedShort(); + int statusParameters = buf.readUnsignedByte(); - decodePowerEngineParameters(position, buf.readUnsignedByte()); + decodePowerEngineParameters(position, statusParameters); + analizeNegativePosition(position, statusParameters); buf.readUnsignedByte(); // reserved -- 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 'src/main/java/org') 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 1e1e55537a6fcb2d5365ea2cbcb9c182d986e83a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 18 May 2023 15:32:19 -0700 Subject: Fix response wrapper --- .../java/org/traccar/web/CharResponseWrapper.java | 82 ---------------------- src/main/java/org/traccar/web/OverrideFilter.java | 4 +- src/main/java/org/traccar/web/ResponseWrapper.java | 82 ++++++++++++++++++++++ 3 files changed, 84 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/org/traccar/web/CharResponseWrapper.java create mode 100644 src/main/java/org/traccar/web/ResponseWrapper.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/CharResponseWrapper.java b/src/main/java/org/traccar/web/CharResponseWrapper.java deleted file mode 100644 index 477fe7928..000000000 --- a/src/main/java/org/traccar/web/CharResponseWrapper.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.web; - -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -public class CharResponseWrapper extends HttpServletResponseWrapper { - - private final ByteArrayOutputStream capture; - private ServletOutputStream output; - - public CharResponseWrapper(HttpServletResponse response) { - super(response); - capture = new ByteArrayOutputStream(response.getBufferSize()); - } - - @Override - public ServletOutputStream getOutputStream() { - if (output == null) { - output = new ServletOutputStream() { - @Override - public boolean isReady() { - return true; - } - - @Override - public void setWriteListener(WriteListener writeListener) { - } - - @Override - public void write(int b) { - capture.write(b); - } - - @Override - public void flush() throws IOException { - capture.flush(); - } - - @Override - public void close() throws IOException { - capture.close(); - } - }; - } - return output; - } - - @Override - public void flushBuffer() throws IOException { - super.flushBuffer(); - if (output != null) { - output.flush(); - } - } - - public byte[] getCapture() throws IOException { - if (output != null) { - output.close(); - } - return capture.toByteArray(); - } - -} diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java index 708632bc1..e6e02514c 100644 --- a/src/main/java/org/traccar/web/OverrideFilter.java +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -45,12 +45,12 @@ public class OverrideFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - CharResponseWrapper wrappedResponse = new CharResponseWrapper((HttpServletResponse) response); + ResponseWrapper wrappedResponse = new ResponseWrapper((HttpServletResponse) response); chain.doFilter(request, wrappedResponse); byte[] bytes = wrappedResponse.getCapture(); - if (wrappedResponse.getContentType().contains("text/html") + if (wrappedResponse.getContentType() != null && wrappedResponse.getContentType().contains("text/html") || ((HttpServletRequest) request).getPathInfo().endsWith("manifest.json")) { Server server; diff --git a/src/main/java/org/traccar/web/ResponseWrapper.java b/src/main/java/org/traccar/web/ResponseWrapper.java new file mode 100644 index 000000000..7c06b67b8 --- /dev/null +++ b/src/main/java/org/traccar/web/ResponseWrapper.java @@ -0,0 +1,82 @@ +/* + * 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.web; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class ResponseWrapper extends HttpServletResponseWrapper { + + private final ByteArrayOutputStream capture; + private ServletOutputStream output; + + public ResponseWrapper(HttpServletResponse response) { + super(response); + capture = new ByteArrayOutputStream(response.getBufferSize()); + } + + @Override + public ServletOutputStream getOutputStream() { + if (output == null) { + output = new ServletOutputStream() { + @Override + public boolean isReady() { + return true; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + } + + @Override + public void write(int b) { + capture.write(b); + } + + @Override + public void flush() throws IOException { + capture.flush(); + } + + @Override + public void close() throws IOException { + capture.close(); + } + }; + } + return output; + } + + @Override + public void flushBuffer() throws IOException { + super.flushBuffer(); + if (output != null) { + output.flush(); + } + } + + public byte[] getCapture() throws IOException { + if (output != null) { + output.close(); + } + return capture.toByteArray(); + } + +} -- cgit v1.2.3 From 39b293b9f66c3c539e180fb2bcf37849335100dc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 18 May 2023 16:16:10 -0700 Subject: Fix override filter --- src/main/java/org/traccar/web/OverrideFilter.java | 40 ++++++++++++---------- src/main/java/org/traccar/web/ResponseWrapper.java | 3 +- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java index e6e02514c..70eb80a67 100644 --- a/src/main/java/org/traccar/web/OverrideFilter.java +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -50,30 +50,32 @@ public class OverrideFilter implements Filter { chain.doFilter(request, wrappedResponse); byte[] bytes = wrappedResponse.getCapture(); - if (wrappedResponse.getContentType() != null && wrappedResponse.getContentType().contains("text/html") - || ((HttpServletRequest) request).getPathInfo().endsWith("manifest.json")) { + if (bytes != null) { + if (wrappedResponse.getContentType() != null && wrappedResponse.getContentType().contains("text/html") + || ((HttpServletRequest) request).getPathInfo().endsWith("manifest.json")) { - Server server; - try { - server = permissionsServiceProvider.get().getServer(); - } catch (StorageException e) { - throw new RuntimeException(e); - } + Server server; + try { + server = permissionsServiceProvider.get().getServer(); + } catch (StorageException e) { + throw new RuntimeException(e); + } - String title = server.getString("title", "Traccar"); - String description = server.getString("description", "Traccar GPS Tracking System"); - String colorPrimary = server.getString("colorPrimary", "#1a237e"); + String title = server.getString("title", "Traccar"); + String description = server.getString("description", "Traccar GPS Tracking System"); + String colorPrimary = server.getString("colorPrimary", "#1a237e"); - String alteredContent = new String(wrappedResponse.getCapture()) - .replace("${title}", title) - .replace("${description}", description) - .replace("${colorPrimary}", colorPrimary); + String alteredContent = new String(wrappedResponse.getCapture()) + .replace("${title}", title) + .replace("${description}", description) + .replace("${colorPrimary}", colorPrimary); - response.setContentLength(alteredContent.length()); - response.getOutputStream().write(alteredContent.getBytes()); + response.setContentLength(alteredContent.length()); + response.getOutputStream().write(alteredContent.getBytes()); - } else { - response.getOutputStream().write(bytes); + } else { + response.getOutputStream().write(bytes); + } } } diff --git a/src/main/java/org/traccar/web/ResponseWrapper.java b/src/main/java/org/traccar/web/ResponseWrapper.java index 7c06b67b8..c6179a33e 100644 --- a/src/main/java/org/traccar/web/ResponseWrapper.java +++ b/src/main/java/org/traccar/web/ResponseWrapper.java @@ -75,8 +75,9 @@ public class ResponseWrapper extends HttpServletResponseWrapper { public byte[] getCapture() throws IOException { if (output != null) { output.close(); + return capture.toByteArray(); } - return capture.toByteArray(); + return null; } } -- cgit v1.2.3 From ebc3ab93b63006c77802c45c793f3a875982dbba Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 18 May 2023 16:42:22 -0700 Subject: Support web overrides --- src/main/java/org/traccar/config/Keys.java | 7 ++++++ .../java/org/traccar/web/ModernDefaultServlet.java | 26 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 4 ++-- 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 162a3fe13..4ebdd49f1 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -753,6 +753,13 @@ public final class Keys { "web.path", List.of(KeyType.CONFIG)); + /** + * Path to a folder with overrides. It can be used for branding to keep custom logos in a separate place. + */ + public static final ConfigKey WEB_OVERRIDE = new StringConfigKey( + "web.override", + List.of(KeyType.CONFIG)); + /** * WebSocket connection timeout in milliseconds. Default timeout is 10 minutes. */ diff --git a/src/main/java/org/traccar/web/ModernDefaultServlet.java b/src/main/java/org/traccar/web/ModernDefaultServlet.java index bae089d6c..7911c0e7f 100644 --- a/src/main/java/org/traccar/web/ModernDefaultServlet.java +++ b/src/main/java/org/traccar/web/ModernDefaultServlet.java @@ -17,11 +17,37 @@ package org.traccar.web; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.util.resource.Resource; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import java.io.File; +import java.io.IOException; public class ModernDefaultServlet extends DefaultServlet { + private Resource overrideResource; + + @Inject + public ModernDefaultServlet(Config config) { + String override = config.getString(Keys.WEB_OVERRIDE); + if (override != null) { + overrideResource = Resource.newResource(new File(override)); + } + } + @Override public Resource getResource(String pathInContext) { + if (overrideResource != null) { + try { + Resource override = overrideResource.addPath(pathInContext); + if (override.exists()) { + return override; + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } return super.getResource(pathInContext.indexOf('.') < 0 ? "/" : pathInContext); } diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index ce1220157..b5d2f2771 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -141,7 +141,7 @@ public class WebServer implements LifecycleObject { } private void initWebApp(ServletContextHandler servletHandler) { - ServletHolder servletHolder = new ServletHolder(ModernDefaultServlet.class); + ServletHolder servletHolder = new ServletHolder(new ModernDefaultServlet(config)); servletHolder.setInitParameter("resourceBase", new File(config.getString(Keys.WEB_PATH)).getAbsolutePath()); servletHolder.setInitParameter("dirAllowed", "false"); if (config.getBoolean(Keys.WEB_DEBUG)) { -- cgit v1.2.3 From e94e7f55aae161cf2fd30bbb2ca217f23627b074 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 May 2023 17:21:52 -0700 Subject: Add SMS enabled flag --- src/main/java/org/traccar/api/resource/ServerResource.java | 8 +++++++- src/main/java/org/traccar/model/Server.java | 14 +++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 6a3b8919e..f334b7a21 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -25,6 +25,7 @@ import org.traccar.helper.LogAction; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.cache.CacheManager; +import org.traccar.sms.SmsManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; @@ -56,6 +57,10 @@ public class ServerResource extends BaseResource { @Inject private MailManager mailManager; + @Inject + @Nullable + private SmsManager smsManager; + @Inject @Nullable private OpenIdProvider openIdProvider; @@ -69,6 +74,7 @@ public class ServerResource extends BaseResource { public Server get() throws StorageException { Server server = storage.getObject(Server.class, new Request(new Columns.All())); server.setEmailEnabled(mailManager.getEmailEnabled()); + server.setTextEnabled(smsManager != null); server.setGeocoderEnabled(geocoder != null); server.setOpenIdEnabled(openIdProvider != null); server.setOpenIdForce(openIdProvider != null && openIdProvider.getForce()); diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index b790ca472..6442186b6 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -228,6 +228,18 @@ public class Server extends ExtendedModel implements UserRestrictions { private boolean geocoderEnabled; + private boolean textEnabled; + + @QueryIgnore + public void setTextEnabled(boolean textEnabled) { + this.textEnabled = textEnabled; + } + + @QueryIgnore + public Boolean getTextEnabled() { + return textEnabled; + } + @QueryIgnore public void setGeocoderEnabled(boolean geocoderEnabled) { this.geocoderEnabled = geocoderEnabled; -- cgit v1.2.3 From e9a93ff35c1f923245ffdde78e4023b434173d64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 23 May 2023 16:17:34 -0700 Subject: Fast summary report --- src/main/java/org/traccar/config/Keys.java | 9 ++ .../org/traccar/reports/SummaryReportProvider.java | 120 ++++++++++++--------- 2 files changed, 77 insertions(+), 52 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 4ebdd49f1..8246fdeac 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1170,6 +1170,15 @@ public final class Keys { "report.periodLimit", List.of(KeyType.CONFIG)); + /** + * Time threshold for fast reports. Fast reports are more efficient, but less accurate and missing some information. + * The value is in seconds. One day by default. + */ + public static final ConfigKey REPORT_FAST_THRESHOLD = new LongConfigKey( + "report.fastThreshold", + List.of(KeyType.CONFIG), + 86400L); + /** * Trips less than minimal duration and minimal distance are ignored. 300 seconds and 500 meters are default. */ diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index f7d9f0325..2226263fa 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,6 +30,10 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -38,10 +42,13 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Paths; +import java.time.Duration; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collection; import java.util.Date; +import java.util.List; public class SummaryReportProvider { @@ -59,96 +66,105 @@ public class SummaryReportProvider { this.storage = storage; } - private SummaryReportItem calculateSummaryResult(Device device, Collection positions) { + private Position getEdgePosition(long deviceId, Date from, Date to, boolean end) throws StorageException { + return storage.getObject(Position.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", deviceId), + new Condition.Between("fixTime", "from", from, "to", to)), + new Order("fixTime", end, 1))); + } + + private Collection calculateDeviceResult( + Device device, Date from, Date to, boolean fast) throws StorageException { + SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(device.getId()); result.setDeviceName(device.getName()); - if (positions != null && !positions.isEmpty()) { - Position firstPosition = null; - Position previousPosition = null; + + Position first = null; + Position last = null; + if (fast) { + first = getEdgePosition(device.getId(), from, to, false); + last = getEdgePosition(device.getId(), from, to, true); + } else { + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); for (Position position : positions) { - if (firstPosition == null) { - firstPosition = position; + if (first == null) { + first = position; } - previousPosition = position; if (position.getSpeed() > result.getMaxSpeed()) { result.setMaxSpeed(position.getSpeed()); } + last = position; } + } + + if (first != null && last != null) { boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); - result.setDistance(PositionUtil.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); - result.setSpentFuel(reportUtils.calculateFuel(firstPosition, previousPosition)); + result.setDistance(PositionUtil.calculateDistance(first, last, !ignoreOdometer)); + result.setSpentFuel(reportUtils.calculateFuel(first, last)); long durationMilliseconds; - if (firstPosition.hasAttribute(Position.KEY_HOURS) && previousPosition.hasAttribute(Position.KEY_HOURS)) { - durationMilliseconds = - previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS); + if (first.hasAttribute(Position.KEY_HOURS) && last.hasAttribute(Position.KEY_HOURS)) { + durationMilliseconds = last.getLong(Position.KEY_HOURS) - first.getLong(Position.KEY_HOURS); result.setEngineHours(durationMilliseconds); } else { - durationMilliseconds = - previousPosition.getFixTime().getTime() - firstPosition.getFixTime().getTime(); + durationMilliseconds = last.getFixTime().getTime() - first.getFixTime().getTime(); } if (durationMilliseconds > 0) { - result.setAverageSpeed( - UnitsConverter.knotsFromMps(result.getDistance() * 1000 / durationMilliseconds)); + result.setAverageSpeed(UnitsConverter.knotsFromMps(result.getDistance() * 1000 / durationMilliseconds)); } if (!ignoreOdometer - && firstPosition.getDouble(Position.KEY_ODOMETER) != 0 - && previousPosition.getDouble(Position.KEY_ODOMETER) != 0) { - result.setStartOdometer(firstPosition.getDouble(Position.KEY_ODOMETER)); - result.setEndOdometer(previousPosition.getDouble(Position.KEY_ODOMETER)); + && first.getDouble(Position.KEY_ODOMETER) != 0 && last.getDouble(Position.KEY_ODOMETER) != 0) { + result.setStartOdometer(first.getDouble(Position.KEY_ODOMETER)); + result.setEndOdometer(last.getDouble(Position.KEY_ODOMETER)); } else { - result.setStartOdometer(firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); - result.setEndOdometer(previousPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); + result.setStartOdometer(first.getDouble(Position.KEY_TOTAL_DISTANCE)); + result.setEndOdometer(last.getDouble(Position.KEY_TOTAL_DISTANCE)); } - result.setStartTime(firstPosition.getFixTime()); - result.setEndTime(previousPosition.getFixTime()); + result.setStartTime(first.getFixTime()); + result.setEndTime(last.getFixTime()); + return List.of(result); } - return result; - } - private int getDay(long userId, Date date) throws StorageException { - Calendar calendar = Calendar.getInstance(UserUtil.getTimezone( - permissionsService.getServer(), permissionsService.getUser(userId))); - calendar.setTime(date); - return calendar.get(Calendar.DAY_OF_MONTH); + return List.of(); } - private Collection calculateSummaryResults( - long userId, Device device, Date from, Date to, boolean daily) throws StorageException { + private Collection calculateDeviceResults( + Device device, ZonedDateTime from, ZonedDateTime to, boolean daily) throws StorageException { - var positions = PositionUtil.getPositions(storage, device.getId(), from, to); + boolean fast = Duration.between(from, to).toSeconds() > config.getLong(Keys.REPORT_FAST_THRESHOLD); var results = new ArrayList(); - if (daily && !positions.isEmpty()) { - int startIndex = 0; - int startDay = getDay(userId, positions.iterator().next().getFixTime()); - for (int i = 0; i < positions.size(); i++) { - int currentDay = getDay(userId, positions.get(i).getFixTime()); - if (currentDay != startDay) { - results.add(calculateSummaryResult(device, positions.subList(startIndex, i))); - startIndex = i; - startDay = currentDay; - } + if (daily) { + while (from.truncatedTo(ChronoUnit.DAYS).isBefore(to.truncatedTo(ChronoUnit.DAYS))) { + ZonedDateTime fromDay = from.truncatedTo(ChronoUnit.DAYS); + ZonedDateTime nextDay = fromDay.plus(1, ChronoUnit.DAYS); + results.addAll(calculateDeviceResult( + device, Date.from(from.toInstant()), Date.from(nextDay.toInstant()), fast)); + from = nextDay; } - results.add(calculateSummaryResult(device, positions.subList(startIndex, positions.size()))); + results.addAll(calculateDeviceResult(device, Date.from(from.toInstant()), Date.from(to.toInstant()), fast)); } else { - results.add(calculateSummaryResult(device, positions)); + results.addAll(calculateDeviceResult(device, Date.from(from.toInstant()), Date.from(to.toInstant()), fast)); } - return results; } public Collection getObjects( - long userId, Collection deviceIds, - Collection groupIds, Date from, Date to, boolean daily) throws StorageException { + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to, boolean daily) throws StorageException { reportUtils.checkPeriodLimit(from, to); + var tz = UserUtil.getTimezone(permissionsService.getServer(), permissionsService.getUser(userId)).toZoneId(); + ArrayList result = new ArrayList<>(); for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { - Collection deviceResults = calculateSummaryResults(userId, device, from, to, daily); + var deviceResults = calculateDeviceResults( + device, from.toInstant().atZone(tz), to.toInstant().atZone(tz), daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { result.add(summaryReport); -- cgit v1.2.3 From cd1ce7c3e89d12f59339ccd2676d7c2bfc1596cf Mon Sep 17 00:00:00 2001 From: geduxas Date: Wed, 24 May 2023 12:47:20 +0300 Subject: Update TeltonikaProtocolDecoder.java Add some IO for FMBxx devices, most of them from lvcan addapter. --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 2f378f30a..ab127bb95 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -247,7 +247,16 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } }); register(80, fmbXXX, (p, b) -> p.set("dataMode", b.readUnsignedByte())); + register(81, fmbXXX, (p, b) -> p.set(Position.KEY_OBD_SPEED, b.readUnsignedByte())); + register(82, fmbXXX, (p, b) -> p.set(Position.KEY_THROTTLE, b.readUnsignedByte())); + register(83, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_USED, b.readUnsignedInt() * 0.1)); + register(84, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_LEVEL, b.readUnsignedShort() * 0.1)); + register(85, fmbXXX, (p, b) -> p.set(Position.KEY_RPM, b.readUnsignedShort())); + register(87, fmbXXX, (p, b) -> p.set(Position.KEY_OBD_ODOMETER, b.readUnsignedInt() * 0.001)); + register(89, fmbXXX, (p, b) -> p.set("fuelLevelPercentage", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); + register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); + register(110, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_CONSUMPTION, b.readUnsignedShort() * 0.1)); register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); register(181, null, (p, b) -> p.set(Position.KEY_PDOP, b.readUnsignedShort() * 0.1)); @@ -256,12 +265,28 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(200, fmbXXX, (p, b) -> p.set("sleepMode", b.readUnsignedByte())); register(205, fmbXXX, (p, b) -> p.set("cid2g", b.readUnsignedShort())); register(206, fmbXXX, (p, b) -> p.set("lac", b.readUnsignedShort())); + register(232, fmbXXX, (p, b) -> p.set("cngStatus", b.readUnsignedByte() > 0)); + register(233, fmbXXX, (p, b) -> p.set("cngUsed", b.readUnsignedInt() * 0.1)); + register(234, fmbXXX, (p, b) -> p.set("cngLevel", b.readUnsignedShort())); + register(235, fmbXXX, (p, b) -> p.set("oilLevel", b.readUnsignedByte())); register(236, null, (p, b) -> { p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); }); register(239, null, (p, b) -> p.set(Position.KEY_IGNITION, b.readUnsignedByte() > 0)); register(240, null, (p, b) -> p.set(Position.KEY_MOTION, b.readUnsignedByte() > 0)); register(241, null, (p, b) -> p.set(Position.KEY_OPERATOR, b.readUnsignedInt())); + register(246, fmbXXX, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_TOW : null); + }); + register(247, fmbXXX, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_ACCIDENT : null); + }); + register(249, fmbXXX, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_JAMMING : null); + }); + register(252, fmbXXX, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_POWER_CUT : null); + }); register(253, null, (p, b) -> { switch (b.readUnsignedByte()) { case 1: -- cgit v1.2.3 From 878a66576bcf3700a24ebe9142a09276064b7870 Mon Sep 17 00:00:00 2001 From: geduxas Date: Wed, 24 May 2023 18:29:05 +0300 Subject: Update TeltonikaProtocolDecoder.java Removed duplicate --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index ab127bb95..70d633e19 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -255,7 +255,6 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(87, fmbXXX, (p, b) -> p.set(Position.KEY_OBD_ODOMETER, b.readUnsignedInt() * 0.001)); register(89, fmbXXX, (p, b) -> p.set("fuelLevelPercentage", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); - register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); register(110, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_CONSUMPTION, b.readUnsignedShort() * 0.1)); register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); -- cgit v1.2.3 From 11bbfb69360937c361b701065cdbc2e90699693e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 May 2023 15:17:38 -0700 Subject: Remove duplicated list --- src/main/java/org/traccar/reports/common/ReportUtils.java | 11 +++++------ src/test/java/org/traccar/reports/ReportUtilsTest.java | 10 +++++----- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index f5aa6d040..cd52b5de4 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -162,7 +162,7 @@ public class ReportUtils { } private TripReportItem calculateTrip( - Device device, ArrayList positions, int startIndex, int endIndex, + Device device, List positions, int startIndex, int endIndex, boolean ignoreOdometer) throws StorageException { Position startTrip = positions.get(startIndex); @@ -228,7 +228,7 @@ public class ReportUtils { } private StopReportItem calculateStop( - Device device, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { + Device device, List positions, int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -275,7 +275,7 @@ public class ReportUtils { @SuppressWarnings("unchecked") private T calculateTripOrStop( - Device device, ArrayList positions, int startIndex, int endIndex, + Device device, List positions, int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { @@ -285,7 +285,7 @@ public class ReportUtils { } } - private boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { + private boolean isMoving(List positions, int index, TripsConfig tripsConfig) { if (tripsConfig.getMinimalNoDataDuration() > 0) { boolean beforeGap = index < positions.size() - 1 && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() @@ -301,14 +301,13 @@ public class ReportUtils { } public Collection detectTripsAndStops( - Device device, Collection positionCollection, boolean ignoreOdometer, + Device device, List positions, boolean ignoreOdometer, Class reportClass) throws StorageException { Collection result = new ArrayList<>(); TripsConfig tripsConfig = new TripsConfig( new AttributeUtil.StorageProvider(config, storage, permissionsService, device)); - ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 22d70c93a..afb0a516f 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -281,7 +281,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testDetectStopsOnly() throws Exception { - Collection data = Arrays.asList( + var data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), position("2016-01-01 00:01:00.000", 0, 0), position("2016-01-01 00:02:00.000", 1, 0), @@ -309,7 +309,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testDetectStopsWithTripCut() throws Exception { - Collection data = Arrays.asList( + var data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), position("2016-01-01 00:01:00.000", 0, 0), position("2016-01-01 00:02:00.000", 0, 0), @@ -337,7 +337,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testDetectStopsStartedFromTrip() throws Exception { - Collection data = Arrays.asList( + var data = Arrays.asList( position("2016-01-01 00:00:00.000", 2, 0), position("2016-01-01 00:01:00.000", 1, 0), position("2016-01-01 00:02:00.000", 0, 0), @@ -365,7 +365,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testDetectStopsMoving() throws Exception { - Collection data = Arrays.asList( + var data = Arrays.asList( position("2016-01-01 00:00:00.000", 5, 0), position("2016-01-01 00:01:00.000", 5, 0), position("2016-01-01 00:02:00.000", 3, 0), @@ -387,7 +387,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testDetectTripAndStopByGap() throws Exception { - Collection data = Arrays.asList( + var data = Arrays.asList( position("2016-01-01 00:00:00.000", 7, 100), position("2016-01-01 00:01:00.000", 7, 300), position("2016-01-01 00:02:00.000", 5, 500), -- cgit v1.2.3 From d304c74cfc870d23718cb7aabfd6038492aade8b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 May 2023 15:23:53 -0700 Subject: Simplify trips and stops --- .../org/traccar/reports/common/ReportUtils.java | 31 ++++++++-------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index cd52b5de4..6c2d5cd72 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -162,19 +162,7 @@ public class ReportUtils { } private TripReportItem calculateTrip( - Device device, List positions, int startIndex, int endIndex, - boolean ignoreOdometer) throws StorageException { - - Position startTrip = positions.get(startIndex); - Position endTrip = positions.get(endIndex); - - double speedMax = 0; - for (int i = startIndex; i <= endIndex; i++) { - double speed = positions.get(i).getSpeed(); - if (speed > speedMax) { - speedMax = speed; - } - } + Device device, Position startTrip, Position endTrip, boolean ignoreOdometer) throws StorageException { TripReportItem trip = new TripReportItem(); @@ -208,7 +196,6 @@ public class ReportUtils { if (tripDuration > 0) { trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); } - trip.setMaxSpeed(speedMax); trip.setSpentFuel(calculateFuel(startTrip, endTrip)); trip.setDriverUniqueId(findDriver(startTrip, endTrip)); @@ -228,10 +215,7 @@ public class ReportUtils { } private StopReportItem calculateStop( - Device device, List positions, int startIndex, int endIndex, boolean ignoreOdometer) { - - Position startStop = positions.get(startIndex); - Position endStop = positions.get(endIndex); + Device device, Position startStop, Position endStop, boolean ignoreOdometer) { StopReportItem stop = new StopReportItem(); @@ -279,9 +263,16 @@ public class ReportUtils { boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - return (T) calculateTrip(device, positions, startIndex, endIndex, ignoreOdometer); + var result = calculateTrip(device, positions.get(startIndex), positions.get(endIndex), ignoreOdometer); + for (int i = startIndex; i <= endIndex; i++) { + double speed = positions.get(i).getSpeed(); + if (speed > result.getMaxSpeed()) { + result.setMaxSpeed(speed); + } + } + return (T) result; } else { - return (T) calculateStop(device, positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateStop(device, positions.get(startIndex), positions.get(endIndex), ignoreOdometer); } } -- cgit v1.2.3 From 886efe231e79255aa86a0056e7bf912fff6069fb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 May 2023 15:37:04 -0700 Subject: Query positions in report utils --- .../org/traccar/reports/StopsReportProvider.java | 11 ++---- .../org/traccar/reports/TripsReportProvider.java | 11 ++---- .../org/traccar/reports/common/ReportUtils.java | 10 +++--- .../java/org/traccar/reports/ReportUtilsTest.java | 39 +++++++++++++--------- 4 files changed, 32 insertions(+), 39 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index a23cee48b..57c57079d 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -20,7 +20,6 @@ import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.DeviceUtil; -import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; @@ -56,12 +55,6 @@ public class StopsReportProvider { this.storage = storage; } - private Collection detectStops(Device device, Date from, Date to) throws StorageException { - boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); - var positions = PositionUtil.getPositions(storage, device.getId(), from, to); - return reportUtils.detectTripsAndStops(device, positions, ignoreOdometer, StopReportItem.class); - } - public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { @@ -69,7 +62,7 @@ public class StopsReportProvider { ArrayList result = new ArrayList<>(); for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { - result.addAll(detectStops(device, from, to)); + result.addAll(reportUtils.detectTripsAndStops(device, from, to, StopReportItem.class)); } return result; } @@ -82,7 +75,7 @@ public class StopsReportProvider { ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { - Collection stops = detectStops(device, from, to); + Collection stops = reportUtils.detectTripsAndStops(device, from, to, StopReportItem.class); DeviceReportSection deviceStops = new DeviceReportSection(); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 2d8989b7a..e6c3e7ffd 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -20,7 +20,6 @@ import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.DeviceUtil; -import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; @@ -56,12 +55,6 @@ public class TripsReportProvider { this.storage = storage; } - private Collection detectTrips(Device device, Date from, Date to) throws StorageException { - boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); - var positions = PositionUtil.getPositions(storage, device.getId(), from, to); - return reportUtils.detectTripsAndStops(device, positions, ignoreOdometer, TripReportItem.class); - } - public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { @@ -69,7 +62,7 @@ public class TripsReportProvider { ArrayList result = new ArrayList<>(); for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { - result.addAll(detectTrips(device, from, to)); + result.addAll(reportUtils.detectTripsAndStops(device, from, to, TripReportItem.class)); } return result; } @@ -82,7 +75,7 @@ public class TripsReportProvider { ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (Device device: DeviceUtil.getAccessibleDevices(storage, userId, deviceIds, groupIds)) { - Collection trips = detectTrips(device, from, to); + Collection trips = reportUtils.detectTripsAndStops(device, from, to, TripReportItem.class); DeviceReportSection deviceTrips = new DeviceReportSection(); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 6c2d5cd72..a930f9439 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -58,7 +58,6 @@ import java.io.OutputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; -import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Locale; @@ -291,14 +290,15 @@ public class ReportUtils { return positions.get(index).getBoolean(Position.KEY_MOTION); } - public Collection detectTripsAndStops( - Device device, List positions, boolean ignoreOdometer, - Class reportClass) throws StorageException { + public List detectTripsAndStops( + Device device, Date from, Date to, Class reportClass) throws StorageException { - Collection result = new ArrayList<>(); + List result = new ArrayList<>(); TripsConfig tripsConfig = new TripsConfig( new AttributeUtil.StorageProvider(config, storage, permissionsService, device)); + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index afb0a516f..d11d2b2e1 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -2,7 +2,6 @@ package org.traccar.reports; import org.apache.velocity.app.VelocityEngine; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; @@ -21,7 +20,6 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; -import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; @@ -33,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -43,7 +42,7 @@ public class ReportUtilsTest extends BaseTest { @BeforeEach public void init() throws StorageException { storage = mock(Storage.class); - when(storage.getObject(any(), any())).thenReturn(mock(Device.class)); + when(storage.getObject(eq(Device.class), any())).thenReturn(mock(Device.class)); } private Date date(String time) throws ParseException { @@ -114,12 +113,13 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 0, 3000), position("2016-01-01 00:15:00.000", 0, 3000), position("2016-01-01 00:25:00.000", 0, 3000)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); Device device = mockDevice(500, 300, 180, 900, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -133,7 +133,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -166,6 +166,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 0, 3000), position("2016-01-01 00:15:00.000", 0, 3000), position("2016-01-01 00:25:00.000", 0, 3000)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); data.get(5).set(Position.KEY_IGNITION, false); @@ -173,7 +174,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -187,7 +188,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); + trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -201,7 +202,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -238,12 +239,13 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:09:00.000", 0, 7000), position("2016-01-01 00:19:00.000", 0, 7000), position("2016-01-01 00:29:00.000", 0, 7000)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); Device device = mockDevice(500, 300, 180, 900, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -257,7 +259,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -288,12 +290,13 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:03:00.000", 0, 0), position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -316,12 +319,13 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:03:00.000", 0, 0), position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -344,12 +348,13 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:12:00.000", 0, 0), position("2016-01-01 00:22:00.000", 0, 0), position("2016-01-01 00:32:00.000", 0, 0)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -372,12 +377,13 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:03:00.000", 5, 0), position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); Device device = mockDevice(500, 300, 200, 900, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -396,12 +402,13 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:23:00.000", 2, 700), position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); + when(storage.getObjects(eq(Position.class), any())).thenReturn(data); Device device = mockDevice(500, 200, 200, 900, false); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -415,7 +422,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 81b3df465cefa6a6aa25334d79c7a2509dfb26d0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 May 2023 17:11:04 -0700 Subject: Add fast trips and stops --- .../org/traccar/reports/common/ReportUtils.java | 83 ++++++++++++++++++---- .../java/org/traccar/reports/ReportUtilsTest.java | 26 +++---- 2 files changed, 82 insertions(+), 27 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index a930f9439..28e3d2ae5 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -37,6 +37,7 @@ import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; +import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; @@ -48,6 +49,7 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.annotation.Nullable; @@ -57,10 +59,13 @@ import java.io.InputStream; import java.io.OutputStream; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.Duration; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Set; +import java.util.stream.Collectors; public class ReportUtils { @@ -161,7 +166,8 @@ public class ReportUtils { } private TripReportItem calculateTrip( - Device device, Position startTrip, Position endTrip, boolean ignoreOdometer) throws StorageException { + Device device, Position startTrip, Position endTrip, double maxSpeed, + boolean ignoreOdometer) throws StorageException { TripReportItem trip = new TripReportItem(); @@ -195,6 +201,7 @@ public class ReportUtils { if (tripDuration > 0) { trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); } + trip.setMaxSpeed(maxSpeed); trip.setSpentFuel(calculateFuel(startTrip, endTrip)); trip.setDriverUniqueId(findDriver(startTrip, endTrip)); @@ -258,20 +265,13 @@ public class ReportUtils { @SuppressWarnings("unchecked") private T calculateTripOrStop( - Device device, List positions, int startIndex, int endIndex, + Device device, Position startPosition, Position endPosition, double maxSpeed, boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - var result = calculateTrip(device, positions.get(startIndex), positions.get(endIndex), ignoreOdometer); - for (int i = startIndex; i <= endIndex; i++) { - double speed = positions.get(i).getSpeed(); - if (speed > result.getMaxSpeed()) { - result.setMaxSpeed(speed); - } - } - return (T) result; + return (T) calculateTrip(device, startPosition, endPosition, maxSpeed, ignoreOdometer); } else { - return (T) calculateStop(device, positions.get(startIndex), positions.get(endIndex), ignoreOdometer); + return (T) calculateStop(device, startPosition, endPosition, ignoreOdometer); } } @@ -293,6 +293,17 @@ public class ReportUtils { public List detectTripsAndStops( Device device, Date from, Date to, Class reportClass) throws StorageException { + long threshold = config.getLong(Keys.REPORT_FAST_THRESHOLD); + if (Duration.between(from.toInstant(), to.toInstant()).toSeconds() > threshold) { + return fastTripsAndStops(device, from, to, reportClass); + } else { + return slowTripsAndStops(device, from, to, reportClass); + } + } + + public List slowTripsAndStops( + Device device, Date from, Date to, Class reportClass) throws StorageException { + List result = new ArrayList<>(); TripsConfig tripsConfig = new TripsConfig( new AttributeUtil.StorageProvider(config, storage, permissionsService, device)); @@ -308,17 +319,23 @@ public class ReportUtils { motionState.setMotionState(initialValue); boolean detected = trips == motionState.getMotionState(); + double maxSpeed = 0; int startEventIndex = detected ? 0 : -1; int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { boolean motion = isMoving(positions, i, tripsConfig); if (motionState.getMotionState() != motion) { if (motion == trips) { - startEventIndex = detected ? startEventIndex : i; + if (!detected) { + startEventIndex = i; + maxSpeed = positions.get(i).getSpeed(); + } startNoEventIndex = -1; } else { startNoEventIndex = i; } + } else { + maxSpeed = Math.max(maxSpeed, positions.get(i).getSpeed()); } MotionProcessor.updateState(motionState, positions.get(i), motion, tripsConfig); @@ -328,7 +345,8 @@ public class ReportUtils { startNoEventIndex = -1; } else if (startEventIndex >= 0 && startNoEventIndex >= 0) { result.add(calculateTripOrStop( - device, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + device, positions.get(startEventIndex), positions.get(startNoEventIndex), + maxSpeed, ignoreOdometer, reportClass)); detected = false; startEventIndex = -1; startNoEventIndex = -1; @@ -338,7 +356,44 @@ public class ReportUtils { if (detected & startEventIndex >= 0 && startEventIndex < positions.size() - 1) { int endIndex = startNoEventIndex >= 0 ? startNoEventIndex : positions.size() - 1; result.add(calculateTripOrStop( - device, positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); + device, positions.get(startEventIndex), positions.get(endIndex), + maxSpeed, ignoreOdometer, reportClass)); + } + } + + return result; + } + + public List fastTripsAndStops( + Device device, Date from, Date to, Class reportClass) throws StorageException { + + List result = new ArrayList<>(); + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); + boolean trips = reportClass.equals(TripReportItem.class); + Set filter = Set.of(Event.TYPE_DEVICE_MOVING, Event.TYPE_DEVICE_STOPPED); + + var events = storage.getObjects(Event.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", device.getId()), + new Condition.Between("eventTime", "from", from, "to", to)), + new Order("eventTime"))); + var filteredEvents = events.stream() + .filter(event -> filter.contains(event.getType())) + .collect(Collectors.toList()); + + Event startEvent = null; + for (Event event : filteredEvents) { + boolean motion = event.getType().equals(Event.TYPE_DEVICE_MOVING); + if (motion == trips) { + startEvent = event; + } else if (startEvent != null) { + Position startPosition = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", startEvent.getPositionId()))); + Position endPosition = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", event.getPositionId()))); + result.add(calculateTripOrStop(device, startPosition, endPosition, 0, ignoreOdometer, reportClass)); + startEvent = null; } } diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index d11d2b2e1..0f14577fd 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -119,7 +119,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); + var trips = reportUtils.slowTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -133,7 +133,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var stops = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -174,7 +174,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); + var trips = reportUtils.slowTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -188,7 +188,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); + trips = reportUtils.slowTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -202,7 +202,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var stops = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -245,7 +245,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); + var trips = reportUtils.slowTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -259,7 +259,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var stops = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -296,7 +296,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var result = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -325,7 +325,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var result = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -354,7 +354,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var result = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -383,7 +383,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var result = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var result = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -408,7 +408,7 @@ public class ReportUtilsTest extends BaseTest { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), mock(VelocityEngine.class), null); - var trips = reportUtils.detectTripsAndStops(device, new Date(), new Date(), TripReportItem.class); + var trips = reportUtils.slowTripsAndStops(device, new Date(), new Date(), TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -422,7 +422,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - var stops = reportUtils.detectTripsAndStops(device, new Date(), new Date(), StopReportItem.class); + var stops = reportUtils.slowTripsAndStops(device, new Date(), new Date(), StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 86511cd68d968c15db66ddfbe831a34be13e8ba1 Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Thu, 25 May 2023 19:58:07 -0400 Subject: Acknowledge mileage alert and decode third input status --- .../traccar/protocol/LaipacProtocolDecoder.java | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index e9570ee11..ede4650b8 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -110,17 +110,25 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { private String decodeEvent(String event, Position position) { - if (event.length() == 1) { - char inputStatus = event.charAt(0); - if (inputStatus >= 'A' && inputStatus <= 'D') { - int inputStatusInt = inputStatus - 'A'; - position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); - position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); - return null; - } + if (event.length() != 1) + return event; + + int inputStatusInt = 0; + char inputStatus = event.charAt(0); + + if (inputStatus >= 'A' && inputStatus <= 'D') { + inputStatusInt = inputStatus - 'A'; + } else if(inputStatus >= 'O' && inputStatus <= 'R') { + inputStatusInt = inputStatus - 'O' + 4; + } else { + return event; } - return event; + position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); + position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + position.set(Position.PREFIX_IN + 3, inputStatusInt & 4); + + return null; } private void sendEventResponse( @@ -132,6 +140,9 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { case "3": responseCode = "d"; break; + case "M": + responseCode = "m"; + break; case "S": case "T": responseCode = "t"; -- cgit v1.2.3 From 03b9409f05c2edef2c1f52dde8bedc2f43184a50 Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Thu, 25 May 2023 20:03:35 -0400 Subject: Fix style check violation --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index ede4650b8..5b9629ff3 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -118,7 +118,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { if (inputStatus >= 'A' && inputStatus <= 'D') { inputStatusInt = inputStatus - 'A'; - } else if(inputStatus >= 'O' && inputStatus <= 'R') { + } else if (inputStatus >= 'O' && inputStatus <= 'R') { inputStatusInt = inputStatus - 'O' + 4; } else { return event; -- cgit v1.2.3 From 6c3b33275e2d8310011c38ed1bc292546e15cae9 Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Thu, 25 May 2023 20:06:59 -0400 Subject: Fix style check violation --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 5b9629ff3..3b654db0c 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -110,8 +110,9 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { private String decodeEvent(String event, Position position) { - if (event.length() != 1) + if (event.length() != 1) { return event; + } int inputStatusInt = 0; char inputStatus = event.charAt(0); -- cgit v1.2.3 From 6cc15fb06c9490e349847e043eea7c188e88794e Mon Sep 17 00:00:00 2001 From: merabtenei Date: Sun, 28 May 2023 21:38:14 +0100 Subject: fix NullPointerException when attribute key is defined and value is set to null, caused by calling .toString() on null. --- src/main/java/org/traccar/model/ExtendedModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 6a4f502f7..d3d247fdd 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -90,7 +90,7 @@ public class ExtendedModel extends BaseModel { } public String getString(String key, String defaultValue) { - if (attributes.containsKey(key)) { + if (attributes.containsKey(key) && attributes.get(key) != null) { return attributes.get(key).toString(); } else { return defaultValue; -- cgit v1.2.3 From 729df52ea52ce5807b6328eb04cf55d3e9cbea81 Mon Sep 17 00:00:00 2001 From: merabtenei Date: Sun, 28 May 2023 21:56:55 +0100 Subject: do not add permission if user is serviceAccount --- src/main/java/org/traccar/api/BaseObjectResource.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 904781e54..b007b7bcd 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -16,6 +16,7 @@ */ package org.traccar.api; +import org.traccar.api.security.ServiceAccountUser; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Group; @@ -70,10 +71,13 @@ public abstract class BaseObjectResource extends BaseResour entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); - storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); - cacheManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); - connectionManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); - LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); + + if (getUserId() != ServiceAccountUser.ID) { + storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); + cacheManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); + connectionManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); + LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); + } return Response.ok(entity).build(); } -- cgit v1.2.3 From 671e8fbdfd90dce91f372750105561fa7d3b472c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 28 May 2023 17:54:08 -0700 Subject: Change default timeout --- src/main/java/org/traccar/config/Keys.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 8246fdeac..d4780ba46 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -761,12 +761,12 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * WebSocket connection timeout in milliseconds. Default timeout is 10 minutes. + * WebSocket connection timeout in milliseconds. Default timeout is 5 minutes. */ public static final ConfigKey WEB_TIMEOUT = new LongConfigKey( "web.timeout", List.of(KeyType.CONFIG), - 60000L); + 300000L); /** * Authentication sessions timeout in seconds. By default no timeout. -- cgit v1.2.3 From 46dabfabdc7b6cc12cbad9863e38ab1ff97c40a5 Mon Sep 17 00:00:00 2001 From: merabtenei Date: Mon, 29 May 2023 16:03:12 +0100 Subject: fix return null value --- src/main/java/org/traccar/model/ExtendedModel.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index d3d247fdd..0a0923ba1 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -90,8 +90,9 @@ public class ExtendedModel extends BaseModel { } public String getString(String key, String defaultValue) { - if (attributes.containsKey(key) && attributes.get(key) != null) { - return attributes.get(key).toString(); + if (attributes.containsKey(key)) { + Object value = attributes.containsKey(key); + return value != null ? value.toString() : null; } else { return defaultValue; } -- cgit v1.2.3 From d244b4bc4999ba3e3dca607bf797c3f7d7f578ff Mon Sep 17 00:00:00 2001 From: merabtenei Date: Mon, 29 May 2023 18:07:31 +0100 Subject: fix typo: replaced .containsKey with .get --- src/main/java/org/traccar/model/ExtendedModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 0a0923ba1..d5cd094da 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -91,7 +91,7 @@ public class ExtendedModel extends BaseModel { public String getString(String key, String defaultValue) { if (attributes.containsKey(key)) { - Object value = attributes.containsKey(key); + Object value = attributes.get(key); return value != null ? value.toString() : null; } else { return defaultValue; -- cgit v1.2.3 From 4cf820b3dd4d8686842d36c81ee8ee3e954b2393 Mon Sep 17 00:00:00 2001 From: merabtenei Date: Mon, 29 May 2023 21:46:54 +0100 Subject: added Battery Level as IO 113 in TeltonikaProtocolDecoder.java --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 70d633e19..c6531c790 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -256,6 +256,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(89, fmbXXX, (p, b) -> p.set("fuelLevelPercentage", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); register(110, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_CONSUMPTION, b.readUnsignedShort() * 0.1)); + register(113, fmbXXX, (p, b) -> p.set(Position.KEY_BATTERY_LEVEL, b.readUnsignedByte())); register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); register(181, null, (p, b) -> p.set(Position.KEY_PDOP, b.readUnsignedShort() * 0.1)); -- cgit v1.2.3 From 854afb13bd8115a17b9c6c4cf739707313a709cf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 May 2023 10:39:21 -0700 Subject: Support file uploading --- .../org/traccar/api/resource/ServerResource.java | 36 ++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index f334b7a21..dcb059b69 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -16,12 +16,14 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.database.OpenIdProvider; -import org.traccar.helper.model.UserUtil; -import org.traccar.mail.MailManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.helper.LogAction; +import org.traccar.helper.model.UserUtil; +import org.traccar.mail.MailManager; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.cache.CacheManager; @@ -36,12 +38,20 @@ import javax.annotation.security.PermitAll; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; import java.util.TimeZone; @@ -51,6 +61,9 @@ import java.util.TimeZone; @Consumes(MediaType.APPLICATION_JSON) public class ServerResource extends BaseResource { + @Inject + private Config config; + @Inject private CacheManager cacheManager; @@ -119,4 +132,23 @@ public class ServerResource extends BaseResource { return Arrays.asList(TimeZone.getAvailableIDs()); } + @Path("file/{path}") + @POST + @Consumes("*/*") + public Response uploadImage(@PathParam("path") String path, File inputFile) throws IOException, StorageException { + permissionsService.checkAdmin(getUserId()); + String root = config.getString(Keys.WEB_OVERRIDE, config.getString(Keys.WEB_PATH)); + + var outputPath = Paths.get(root, path); + var directoryPath = outputPath.getParent(); + if (directoryPath != null) { + Files.createDirectories(directoryPath); + } + + try (var input = new FileInputStream(inputFile); var output = new FileOutputStream(outputPath.toFile())) { + input.transferTo(output); + } + return Response.ok().build(); + } + } -- cgit v1.2.3 From 8de9a36abef8e66be4fcc248b49045ffd3b5f7ae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 May 2023 11:41:03 -0700 Subject: Handle missing GoSafe fields --- .../java/org/traccar/protocol/GoSafeProtocolDecoder.java | 12 ++++++------ .../java/org/traccar/protocol/GoSafeProtocolDecoderTest.java | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index 77649a041..f17ea0e08 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -93,14 +93,14 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(values[index - 1]))); } position.setCourse(Integer.parseInt(values[index++])); - if (index < values.length) { - position.setAltitude(Integer.parseInt(values[index++])); + if (index < values.length && !values[index++].isEmpty()) { + position.setAltitude(Integer.parseInt(values[index - 1])); } - if (index < values.length) { - position.set(Position.KEY_HDOP, Double.parseDouble(values[index++])); + if (index < values.length && !values[index++].isEmpty()) { + position.set(Position.KEY_HDOP, Double.parseDouble(values[index - 1])); } - if (index < values.length) { - position.set(Position.KEY_VDOP, Double.parseDouble(values[index++])); + if (index < values.length && !values[index++].isEmpty()) { + position.set(Position.KEY_VDOP, Double.parseDouble(values[index - 1])); } break; case "GSM": diff --git a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java index ad944d73a..3e1349a80 100644 --- a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class GoSafeProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, false, text( "*GS06,357330050846344,RST#")); + verifyPositions(decoder, text( + "*GS06,353218073585128,181255300523,,SYS:Smart Track;V9.31;V1.1.5,GPS:A;5;N31.551856;E74.366920;0;0;;2.15;2.64,COT:0,ADC:10.78;0.02,DTT:4002;E1;0;0;0;1$181325300523,,SYS:Smart Track;V9.31;V1.1.5,GPS:A;6;N31.551856;E74.366920;0;0;;2.05;2.13,COT:0,ADC:10.79;0.02,DTT:4002;E1;0;0;0;1#")); + verifyAttribute(decoder, text( "*GS06,356449068350122,013519070819,,SYS:G6S;V3.37;V1.1.8,GPS:A;12;N23.169866;E113.450728;0;255;54;0.79,COT:18779;,ADC:12.66;0.58,DTT:4084;E1;0;0;0;1,IWD:0;1;ad031652643fff28;23.2;1;1;86031652504fff28;24.3;2;1;e603165252a5ff28;24.2;3;1;bb0416557da6ff28;24.0#"), Position.PREFIX_TEMP + 3, 24.0); -- cgit v1.2.3 From 4d6d6466e9c0abfd8aa06d36189b81cda3107c8e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 May 2023 13:58:30 -0700 Subject: Remove unused class --- .../org/traccar/protocol/NdtpV6FrameDecoder.java | 32 ---------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java b/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java deleted file mode 100644 index 5b610013a..000000000 --- a/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.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; - } - -} -- cgit v1.2.3 From fdbd269b9b99de074e2fd9d99d1702620102801b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 4 Jun 2023 17:59:44 -0700 Subject: Handle decimal temperature --- src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java index 4e5200f37..4d8e7e7ea 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java @@ -153,7 +153,7 @@ public class FreematicsProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, Integer.parseInt(value)); break; case 0x82: - position.set(Position.KEY_DEVICE_TEMP, Integer.parseInt(value) * 0.1); + position.set(Position.KEY_DEVICE_TEMP, Double.parseDouble(value) * 0.1); break; case 0x104: position.set(Position.KEY_ENGINE_LOAD, Integer.parseInt(value)); diff --git a/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java index dae3815ac..53ed07da7 100644 --- a/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class FreematicsProtocolDecoderTest extends ProtocolTest { var decoder = inject(new FreematicsProtocolDecoder(null)); + verifyPositions(decoder, text( + "UCFLFAYM#0:33770,24:300,82:53.000000,*F9")); + verifyPositions(decoder, text( "M0ZR4X0#0:204391,11:140221,10:8445000,A:49.215920,B:18.737755,C:410,D:0,E:208,24:1252,20:0;0;0,82:47*B5")); -- cgit v1.2.3 From 1df3562c439ac8d23c1f03e60acba39468de138c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 5 Jun 2023 19:51:41 -0700 Subject: Handle missing positions (fix #5104) --- src/main/java/org/traccar/reports/common/ReportUtils.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 28e3d2ae5..995e92676 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -392,7 +392,10 @@ public class ReportUtils { new Columns.All(), new Condition.Equals("id", startEvent.getPositionId()))); Position endPosition = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", event.getPositionId()))); - result.add(calculateTripOrStop(device, startPosition, endPosition, 0, ignoreOdometer, reportClass)); + if (startPosition != null && endPosition != null) { + result.add(calculateTripOrStop( + device, startPosition, endPosition, 0, ignoreOdometer, reportClass)); + } startEvent = null; } } -- cgit v1.2.3 From 3c8acbd681409a068f3428ce2cbd8cf002d0b974 Mon Sep 17 00:00:00 2001 From: "Rafael E. Ajuria" Date: Wed, 7 Jun 2023 02:27:52 +0000 Subject: redis broadcast service --- .../traccar/broadcast/RedisBroadcastService.java | 206 +++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 src/main/java/org/traccar/broadcast/RedisBroadcastService.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/broadcast/RedisBroadcastService.java b/src/main/java/org/traccar/broadcast/RedisBroadcastService.java new file mode 100644 index 000000000..a6968c894 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/RedisBroadcastService.java @@ -0,0 +1,206 @@ +/* + * 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.broadcast; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Permission; +import org.traccar.model.Position; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPubSub; + +public class RedisBroadcastService implements BroadcastService { + + private static final Logger LOGGER = LoggerFactory.getLogger(RedisBroadcastService.class); + + private final ObjectMapper objectMapper; + + private final ExecutorService service = Executors.newSingleThreadExecutor(); + + private final Set listeners = new HashSet<>(); + + private final String url; + private final String pubsubChannel = "traccar:cast"; + + private final Jedis subscriberJedis; + private final Jedis publisherJedis; + + private final String id; + + public RedisBroadcastService(Config config, ObjectMapper objectMapper) throws IOException { + this.objectMapper = objectMapper; + url = config.getString(Keys.BROADCAST_ADDRESS); + + subscriberJedis = new Jedis(url); + publisherJedis = new Jedis(url); + + // id that will be used to identify this instance of the server + id = String.valueOf(System.currentTimeMillis()); + } + + @Override + public boolean singleInstance() { + return false; + } + + @Override + public void registerListener(BroadcastInterface listener) { + listeners.add(listener); + } + + @Override + public void updateDevice(boolean local, Device device) { + BroadcastMessage message = new BroadcastMessage(); + message.setDevice(device); + sendMessage(message); + } + + @Override + public void updatePosition(boolean local, Position position) { + BroadcastMessage message = new BroadcastMessage(); + message.setPosition(position); + sendMessage(message); + } + + @Override + public void updateEvent(boolean local, long userId, Event event) { + BroadcastMessage message = new BroadcastMessage(); + message.setUserId(userId); + message.setEvent(event); + sendMessage(message); + } + + @Override + public void updateCommand(boolean local, long deviceId) { + BroadcastMessage message = new BroadcastMessage(); + message.setCommandDeviceId(deviceId); + sendMessage(message); + } + + @Override + public void invalidateObject(boolean local, Class clazz, long id) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz), id)); + sendMessage(message); + } + + @Override + public void invalidatePermission( + boolean local, + Class clazz1, long id1, + Class clazz2, long id2) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz1), id1, Permission.getKey(clazz2), id2)); + sendMessage(message); + } + + private void sendMessage(BroadcastMessage message) { + try { + String payload = id + ":" + objectMapper.writeValueAsString(message); + publisherJedis.publish(pubsubChannel, payload); + } catch (IOException e) { + LOGGER.warn("Broadcast failed", e); + } + } + + private void handleMessage(BroadcastMessage message) { + if (message.getDevice() != null) { + listeners.forEach(listener -> listener.updateDevice(false, message.getDevice())); + } else if (message.getPosition() != null) { + listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); + } else if (message.getUserId() != null && message.getEvent() != null) { + listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); + } else if (message.getCommandDeviceId() != null) { + listeners.forEach(listener -> listener.updateCommand(false, message.getCommandDeviceId())); + } else if (message.getChanges() != null) { + var iterator = message.getChanges().entrySet().iterator(); + if (iterator.hasNext()) { + var first = iterator.next(); + if (iterator.hasNext()) { + var second = iterator.next(); + listeners.forEach(listener -> listener.invalidatePermission( + false, + Permission.getKeyClass(first.getKey()), first.getValue(), + Permission.getKeyClass(second.getKey()), second.getValue())); + } else { + listeners.forEach(listener -> listener.invalidateObject( + false, + Permission.getKeyClass(first.getKey()), first.getValue())); + } + } + } + } + + @Override + public void start() throws IOException { + service.submit(receiver); + } + + @Override + public void stop() { + service.shutdown(); + } + + private final Runnable receiver = new Runnable() { + @Override + public void run() { + subscriberJedis.subscribe(new JedisPubSub() { + @Override + public void onMessage(String channel, String message) { + try { + String[] parts = message.split(":", 2); + if (channel == pubsubChannel && parts.length == 2 && !id.equals(parts[0])) { + handleMessage(objectMapper.readValue(parts[1], BroadcastMessage.class)); + } + } catch (IOException e) { + LOGGER.warn("Broadcast handleMessage failed", e); + } + } + }, pubsubChannel); + + while (!service.isShutdown()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + break; + } + } + + try { + subscriberJedis.close(); + publisherJedis.close(); + } catch (Exception e) { + LOGGER.warn("Failed to close pubsub", e); + throw new RuntimeException(e); + } + } + }; + +} -- cgit v1.2.3 From cfd91d45b6731e6632ebb8a4913f807bab510707 Mon Sep 17 00:00:00 2001 From: "Rafael E. Ajuria" Date: Wed, 7 Jun 2023 02:28:53 +0000 Subject: redis broadcast implementation --- src/main/java/org/traccar/MainModule.java | 11 ++++++++++- src/main/java/org/traccar/config/Keys.java | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 6a2fe21c3..b1a8006ee 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -28,6 +28,7 @@ import io.netty.util.Timer; import org.apache.velocity.app.VelocityEngine; import org.traccar.broadcast.BroadcastService; import org.traccar.broadcast.MulticastBroadcastService; +import org.traccar.broadcast.RedisBroadcastService; import org.traccar.broadcast.NullBroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -340,8 +341,16 @@ public class MainModule extends AbstractModule { @Provides public static BroadcastService provideBroadcastService( Config config, ObjectMapper objectMapper) throws IOException { + String broadcastType = config.getString(Keys.BROADCAST_TYPE); if (config.hasKey(Keys.BROADCAST_ADDRESS)) { - return new MulticastBroadcastService(config, objectMapper); + switch (broadcastType) { + case "multicast": + return new MulticastBroadcastService(config, objectMapper); + case "redis": + return new RedisBroadcastService(config, objectMapper); + default: + return new NullBroadcastService(); + } } return new NullBroadcastService(); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index d4780ba46..6f42e8937 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1755,6 +1755,14 @@ public final class Keys { List.of(KeyType.CONFIG), "time,position,speed,course,accuracy,result"); + /** + * Broadcast method. Available options are "multicast" and "redis". Default is "multicast". + */ + public static final ConfigKey BROADCAST_TYPE = new StringConfigKey( + "broadcast.type", + List.of(KeyType.CONFIG), + "multicast"); + /** * Multicast interface. It can be either an IP address or an interface name. */ -- cgit v1.2.3 From ffbfba88830561b27e1d15857fed664f4b7813ba Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 7 Jun 2023 06:49:14 -0700 Subject: Increase frame limit --- src/main/java/org/traccar/protocol/Minifinder2Protocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index 61a43d8db..842194235 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -35,7 +35,7 @@ public class Minifinder2Protocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1200, 2, 2, 4, 0, true)); + pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 2048, 2, 2, 4, 0, true)); pipeline.addLast(new Minifinder2ProtocolEncoder(Minifinder2Protocol.this)); pipeline.addLast(new Minifinder2ProtocolDecoder(Minifinder2Protocol.this)); } -- cgit v1.2.3 From 3397d4f07ef7fae909c0d6258dbc1263c4acc68b Mon Sep 17 00:00:00 2001 From: "Rafael E. Ajuria" Date: Thu, 8 Jun 2023 01:52:09 +0000 Subject: Add BaseBroadcastService pr comment adjustments --- src/main/java/org/traccar/MainModule.java | 2 +- .../traccar/broadcast/BaseBroadcastService.java | 118 ++++++++++++++ .../broadcast/MulticastBroadcastService.java | 92 +---------- .../traccar/broadcast/RedisBroadcastService.java | 176 ++++++--------------- src/main/java/org/traccar/config/Keys.java | 2 +- 5 files changed, 172 insertions(+), 218 deletions(-) create mode 100644 src/main/java/org/traccar/broadcast/BaseBroadcastService.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b1a8006ee..29d846154 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -349,7 +349,7 @@ public class MainModule extends AbstractModule { case "redis": return new RedisBroadcastService(config, objectMapper); default: - return new NullBroadcastService(); + break; } } return new NullBroadcastService(); diff --git a/src/main/java/org/traccar/broadcast/BaseBroadcastService.java b/src/main/java/org/traccar/broadcast/BaseBroadcastService.java new file mode 100644 index 000000000..1ed639dfd --- /dev/null +++ b/src/main/java/org/traccar/broadcast/BaseBroadcastService.java @@ -0,0 +1,118 @@ +/* + * 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.broadcast; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Permission; +import org.traccar.model.Position; + +public abstract class BaseBroadcastService implements BroadcastService { + + private final Set listeners = new HashSet<>(); + + @Override + public boolean singleInstance() { + return true; + } + + @Override + public void registerListener(BroadcastInterface listener) { + listeners.add(listener); + } + + @Override + public void updateDevice(boolean local, Device device) { + BroadcastMessage message = new BroadcastMessage(); + message.setDevice(device); + sendMessage(message); + } + + @Override + public void updatePosition(boolean local, Position position) { + BroadcastMessage message = new BroadcastMessage(); + message.setPosition(position); + sendMessage(message); + } + + @Override + public void updateEvent(boolean local, long userId, Event event) { + BroadcastMessage message = new BroadcastMessage(); + message.setUserId(userId); + message.setEvent(event); + sendMessage(message); + } + + @Override + public void updateCommand(boolean local, long deviceId) { + BroadcastMessage message = new BroadcastMessage(); + message.setCommandDeviceId(deviceId); + sendMessage(message); + } + + @Override + public void invalidateObject(boolean local, Class clazz, long id) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz), id)); + sendMessage(message); + } + + @Override + public void invalidatePermission( + boolean local, + Class clazz1, long id1, + Class clazz2, long id2) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz1), id1, Permission.getKey(clazz2), id2)); + sendMessage(message); + } + + protected abstract void sendMessage(BroadcastMessage message); + + protected void handleMessage(BroadcastMessage message) { + if (message.getDevice() != null) { + listeners.forEach(listener -> listener.updateDevice(false, message.getDevice())); + } else if (message.getPosition() != null) { + listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); + } else if (message.getUserId() != null && message.getEvent() != null) { + listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); + } else if (message.getCommandDeviceId() != null) { + listeners.forEach(listener -> listener.updateCommand(false, message.getCommandDeviceId())); + } else if (message.getChanges() != null) { + var iterator = message.getChanges().entrySet().iterator(); + if (iterator.hasNext()) { + var first = iterator.next(); + if (iterator.hasNext()) { + var second = iterator.next(); + listeners.forEach(listener -> listener.invalidatePermission( + false, + Permission.getKeyClass(first.getKey()), first.getValue(), + Permission.getKeyClass(second.getKey()), second.getValue())); + } else { + listeners.forEach(listener -> listener.invalidateObject( + false, + Permission.getKeyClass(first.getKey()), first.getValue())); + } + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index b1b66f1e3..1c02b319b 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -20,11 +20,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.model.BaseModel; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Permission; -import org.traccar.model.Position; import java.io.IOException; import java.net.DatagramPacket; @@ -34,13 +29,10 @@ import java.net.InetSocketAddress; import java.net.MulticastSocket; import java.net.NetworkInterface; import java.nio.charset.StandardCharsets; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -public class MulticastBroadcastService implements BroadcastService { +public class MulticastBroadcastService extends BaseBroadcastService { private static final Logger LOGGER = LoggerFactory.getLogger(MulticastBroadcastService.class); @@ -55,8 +47,6 @@ public class MulticastBroadcastService implements BroadcastService { private final ExecutorService service = Executors.newSingleThreadExecutor(); private final byte[] receiverBuffer = new byte[4096]; - private final Set listeners = new HashSet<>(); - public MulticastBroadcastService(Config config, ObjectMapper objectMapper) throws IOException { this.objectMapper = objectMapper; port = config.getInteger(Keys.BROADCAST_PORT); @@ -76,57 +66,7 @@ public class MulticastBroadcastService implements BroadcastService { } @Override - public void registerListener(BroadcastInterface listener) { - listeners.add(listener); - } - - @Override - public void updateDevice(boolean local, Device device) { - BroadcastMessage message = new BroadcastMessage(); - message.setDevice(device); - sendMessage(message); - } - - @Override - public void updatePosition(boolean local, Position position) { - BroadcastMessage message = new BroadcastMessage(); - message.setPosition(position); - sendMessage(message); - } - - @Override - public void updateEvent(boolean local, long userId, Event event) { - BroadcastMessage message = new BroadcastMessage(); - message.setUserId(userId); - message.setEvent(event); - sendMessage(message); - } - - @Override - public void updateCommand(boolean local, long deviceId) { - BroadcastMessage message = new BroadcastMessage(); - message.setCommandDeviceId(deviceId); - sendMessage(message); - } - - @Override - public void invalidateObject(boolean local, Class clazz, long id) { - BroadcastMessage message = new BroadcastMessage(); - message.setChanges(Map.of(Permission.getKey(clazz), id)); - sendMessage(message); - } - - @Override - public void invalidatePermission( - boolean local, - Class clazz1, long id1, - Class clazz2, long id2) { - BroadcastMessage message = new BroadcastMessage(); - message.setChanges(Map.of(Permission.getKey(clazz1), id1, Permission.getKey(clazz2), id2)); - sendMessage(message); - } - - private void sendMessage(BroadcastMessage message) { + protected void sendMessage(BroadcastMessage message) { try { byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group); @@ -136,34 +76,6 @@ public class MulticastBroadcastService implements BroadcastService { } } - private void handleMessage(BroadcastMessage message) { - if (message.getDevice() != null) { - listeners.forEach(listener -> listener.updateDevice(false, message.getDevice())); - } else if (message.getPosition() != null) { - listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); - } else if (message.getUserId() != null && message.getEvent() != null) { - listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); - } else if (message.getCommandDeviceId() != null) { - listeners.forEach(listener -> listener.updateCommand(false, message.getCommandDeviceId())); - } else if (message.getChanges() != null) { - var iterator = message.getChanges().entrySet().iterator(); - if (iterator.hasNext()) { - var first = iterator.next(); - if (iterator.hasNext()) { - var second = iterator.next(); - listeners.forEach(listener -> listener.invalidatePermission( - false, - Permission.getKeyClass(first.getKey()), first.getValue(), - Permission.getKeyClass(second.getKey()), second.getValue())); - } else { - listeners.forEach(listener -> listener.invalidateObject( - false, - Permission.getKeyClass(first.getKey()), first.getValue())); - } - } - } - } - @Override public void start() throws IOException { service.submit(receiver); diff --git a/src/main/java/org/traccar/broadcast/RedisBroadcastService.java b/src/main/java/org/traccar/broadcast/RedisBroadcastService.java index a6968c894..e619fef60 100644 --- a/src/main/java/org/traccar/broadcast/RedisBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/RedisBroadcastService.java @@ -20,23 +20,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.model.BaseModel; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Permission; -import org.traccar.model.Position; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPubSub; +import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.exceptions.JedisException; -public class RedisBroadcastService implements BroadcastService { +public class RedisBroadcastService extends BaseBroadcastService { private static final Logger LOGGER = LoggerFactory.getLogger(RedisBroadcastService.class); @@ -44,25 +38,25 @@ public class RedisBroadcastService implements BroadcastService { private final ExecutorService service = Executors.newSingleThreadExecutor(); - private final Set listeners = new HashSet<>(); - private final String url; - private final String pubsubChannel = "traccar:cast"; + private final String channel = "traccar"; - private final Jedis subscriberJedis; - private final Jedis publisherJedis; + private Jedis subscriber; + private Jedis publisher; - private final String id; + private final String id = UUID.randomUUID().toString(); public RedisBroadcastService(Config config, ObjectMapper objectMapper) throws IOException { this.objectMapper = objectMapper; url = config.getString(Keys.BROADCAST_ADDRESS); - subscriberJedis = new Jedis(url); - publisherJedis = new Jedis(url); - - // id that will be used to identify this instance of the server - id = String.valueOf(System.currentTimeMillis()); + try { + subscriber = new Jedis(url); + publisher = new Jedis(url); + subscriber.connect(); + } catch (JedisConnectionException e) { + throw new IOException(e); + } } @Override @@ -71,90 +65,14 @@ public class RedisBroadcastService implements BroadcastService { } @Override - public void registerListener(BroadcastInterface listener) { - listeners.add(listener); - } - - @Override - public void updateDevice(boolean local, Device device) { - BroadcastMessage message = new BroadcastMessage(); - message.setDevice(device); - sendMessage(message); - } - - @Override - public void updatePosition(boolean local, Position position) { - BroadcastMessage message = new BroadcastMessage(); - message.setPosition(position); - sendMessage(message); - } - - @Override - public void updateEvent(boolean local, long userId, Event event) { - BroadcastMessage message = new BroadcastMessage(); - message.setUserId(userId); - message.setEvent(event); - sendMessage(message); - } - - @Override - public void updateCommand(boolean local, long deviceId) { - BroadcastMessage message = new BroadcastMessage(); - message.setCommandDeviceId(deviceId); - sendMessage(message); - } - - @Override - public void invalidateObject(boolean local, Class clazz, long id) { - BroadcastMessage message = new BroadcastMessage(); - message.setChanges(Map.of(Permission.getKey(clazz), id)); - sendMessage(message); - } - - @Override - public void invalidatePermission( - boolean local, - Class clazz1, long id1, - Class clazz2, long id2) { - BroadcastMessage message = new BroadcastMessage(); - message.setChanges(Map.of(Permission.getKey(clazz1), id1, Permission.getKey(clazz2), id2)); - sendMessage(message); - } - - private void sendMessage(BroadcastMessage message) { + protected void sendMessage(BroadcastMessage message) { try { String payload = id + ":" + objectMapper.writeValueAsString(message); - publisherJedis.publish(pubsubChannel, payload); + publisher.publish(channel, payload); } catch (IOException e) { LOGGER.warn("Broadcast failed", e); - } - } - - private void handleMessage(BroadcastMessage message) { - if (message.getDevice() != null) { - listeners.forEach(listener -> listener.updateDevice(false, message.getDevice())); - } else if (message.getPosition() != null) { - listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); - } else if (message.getUserId() != null && message.getEvent() != null) { - listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); - } else if (message.getCommandDeviceId() != null) { - listeners.forEach(listener -> listener.updateCommand(false, message.getCommandDeviceId())); - } else if (message.getChanges() != null) { - var iterator = message.getChanges().entrySet().iterator(); - if (iterator.hasNext()) { - var first = iterator.next(); - if (iterator.hasNext()) { - var second = iterator.next(); - listeners.forEach(listener -> listener.invalidatePermission( - false, - Permission.getKeyClass(first.getKey()), first.getValue(), - Permission.getKeyClass(second.getKey()), second.getValue())); - } else { - listeners.forEach(listener -> listener.invalidateObject( - false, - Permission.getKeyClass(first.getKey()), first.getValue())); - } - } + } catch (JedisConnectionException e) { + LOGGER.warn("Broadcast failed", e); } } @@ -165,39 +83,45 @@ public class RedisBroadcastService implements BroadcastService { @Override public void stop() { + try { + if (subscriber != null) { + subscriber.close(); + subscriber = null; + } + } catch (JedisException e) { + LOGGER.warn("Subscriber close failed", e); + } + try { + if (publisher != null) { + publisher.close(); + publisher = null; + } + } catch (JedisException e) { + LOGGER.warn("Publisher close failed", e); + } service.shutdown(); } private final Runnable receiver = new Runnable() { @Override public void run() { - subscriberJedis.subscribe(new JedisPubSub() { - @Override - public void onMessage(String channel, String message) { - try { - String[] parts = message.split(":", 2); - if (channel == pubsubChannel && parts.length == 2 && !id.equals(parts[0])) { - handleMessage(objectMapper.readValue(parts[1], BroadcastMessage.class)); + try { + subscriber.subscribe(new JedisPubSub() { + @Override + public void onMessage(String messageChannel, String message) { + try { + String[] parts = message.split(":", 2); + if (messageChannel == channel && parts.length == 2 && !id.equals(parts[0])) { + handleMessage(objectMapper.readValue(parts[1], BroadcastMessage.class)); + } + } catch (IOException e) { + LOGGER.warn("Broadcast handleMessage failed", e); } - } catch (IOException e) { - LOGGER.warn("Broadcast handleMessage failed", e); } - } - }, pubsubChannel); - - while (!service.isShutdown()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - break; - } - } - - try { - subscriberJedis.close(); - publisherJedis.close(); - } catch (Exception e) { - LOGGER.warn("Failed to close pubsub", e); + }, channel); + } catch (JedisConnectionException e) { + throw new RuntimeException(e); + } catch (JedisException e) { throw new RuntimeException(e); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6f42e8937..381e3a108 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1771,7 +1771,7 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Multicast address for broadcasting synchronization events. + * Multicast address or Redis URL for broadcasting synchronization events. */ public static final ConfigKey BROADCAST_ADDRESS = new StringConfigKey( "broadcast.address", -- cgit v1.2.3 From a39af3b4d72f3ed8a6dfe868d365d6bbf34e18d3 Mon Sep 17 00:00:00 2001 From: "Rafael E. Ajuria" Date: Fri, 9 Jun 2023 01:15:52 +0000 Subject: cleanup Breaking change: if using multicast must set broadcast.type="multicast" --- src/main/java/org/traccar/MainModule.java | 18 +++++++----------- .../org/traccar/broadcast/BaseBroadcastService.java | 2 +- src/main/java/org/traccar/config/Keys.java | 5 +++-- 3 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 29d846154..950a7278a 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -341,18 +341,14 @@ public class MainModule extends AbstractModule { @Provides public static BroadcastService provideBroadcastService( Config config, ObjectMapper objectMapper) throws IOException { - String broadcastType = config.getString(Keys.BROADCAST_TYPE); - if (config.hasKey(Keys.BROADCAST_ADDRESS)) { - switch (broadcastType) { - case "multicast": - return new MulticastBroadcastService(config, objectMapper); - case "redis": - return new RedisBroadcastService(config, objectMapper); - default: - break; - } + switch (config.getString(Keys.BROADCAST_TYPE)) { + case "multicast": + return new MulticastBroadcastService(config, objectMapper); + case "redis": + return new RedisBroadcastService(config, objectMapper); + default: + return new NullBroadcastService(); } - return new NullBroadcastService(); } @Singleton diff --git a/src/main/java/org/traccar/broadcast/BaseBroadcastService.java b/src/main/java/org/traccar/broadcast/BaseBroadcastService.java index 1ed639dfd..a95d333f2 100644 --- a/src/main/java/org/traccar/broadcast/BaseBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/BaseBroadcastService.java @@ -115,4 +115,4 @@ public abstract class BaseBroadcastService implements BroadcastService { } } -} \ No newline at end of file +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 381e3a108..78e081ce5 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1756,12 +1756,13 @@ public final class Keys { "time,position,speed,course,accuracy,result"); /** - * Broadcast method. Available options are "multicast" and "redis". Default is "multicast". + * Broadcast method. Available options are "multicast" and "redis". By default (if the value is not + * specified or does not matches available options) server disables broadcast. */ public static final ConfigKey BROADCAST_TYPE = new StringConfigKey( "broadcast.type", List.of(KeyType.CONFIG), - "multicast"); + ""); /** * Multicast interface. It can be either an IP address or an interface name. -- cgit v1.2.3 From dc22bc5feef7887d3baec1b2904fc18e1d067378 Mon Sep 17 00:00:00 2001 From: "Rafael E. Ajuria" Date: Sat, 10 Jun 2023 14:01:11 +0000 Subject: cleanup broadcast type --- src/main/java/org/traccar/MainModule.java | 17 ++++++++++------- src/main/java/org/traccar/config/Keys.java | 3 +-- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 950a7278a..b7bdbc6bf 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -341,14 +341,17 @@ public class MainModule extends AbstractModule { @Provides public static BroadcastService provideBroadcastService( Config config, ObjectMapper objectMapper) throws IOException { - switch (config.getString(Keys.BROADCAST_TYPE)) { - case "multicast": - return new MulticastBroadcastService(config, objectMapper); - case "redis": - return new RedisBroadcastService(config, objectMapper); - default: - return new NullBroadcastService(); + if (config.hasKey(Keys.BROADCAST_TYPE)) { + switch (config.getString(Keys.BROADCAST_TYPE)) { + case "multicast": + return new MulticastBroadcastService(config, objectMapper); + case "redis": + return new RedisBroadcastService(config, objectMapper); + default: + break; + } } + return new NullBroadcastService(); } @Singleton diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 78e081ce5..1ff1d1b51 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1761,8 +1761,7 @@ public final class Keys { */ public static final ConfigKey BROADCAST_TYPE = new StringConfigKey( "broadcast.type", - List.of(KeyType.CONFIG), - ""); + List.of(KeyType.CONFIG)); /** * Multicast interface. It can be either an IP address or an interface name. -- cgit v1.2.3 From 144aaea2f46d8936009f9320279f58a118b0653c Mon Sep 17 00:00:00 2001 From: "Rafael E. Ajuria" Date: Sat, 10 Jun 2023 19:05:46 +0000 Subject: fix: compare string by value --- src/main/java/org/traccar/broadcast/RedisBroadcastService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/broadcast/RedisBroadcastService.java b/src/main/java/org/traccar/broadcast/RedisBroadcastService.java index e619fef60..e87ad5e61 100644 --- a/src/main/java/org/traccar/broadcast/RedisBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/RedisBroadcastService.java @@ -111,7 +111,7 @@ public class RedisBroadcastService extends BaseBroadcastService { public void onMessage(String messageChannel, String message) { try { String[] parts = message.split(":", 2); - if (messageChannel == channel && parts.length == 2 && !id.equals(parts[0])) { + if (messageChannel.equals(channel) && parts.length == 2 && !id.equals(parts[0])) { handleMessage(objectMapper.readValue(parts[1], BroadcastMessage.class)); } } catch (IOException e) { -- cgit v1.2.3 From 13544022b3bf855fdc63893aa3040ecc78fb4dbb Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Sun, 11 Jun 2023 11:05:46 +0200 Subject: Ruptela IO decoding for Odometer, OBD Odometer and OBD Speed --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 77df0deb7..8672d104a 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -108,6 +108,9 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 30: position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); break; + case 65: + position.set(Position.KEY_ODOMETER, readValue(buf, length, true)); + break; case 74: position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; @@ -116,6 +119,9 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 80: position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); break; + case 95: + position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(readValue(buf, length, true))); + break; case 134: if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); @@ -129,6 +135,9 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 197: position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); break; + case 645: + position.set(Position.KEY_OBD_ODOMETER, readValue(buf, length, true) * 1000); + break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); break; -- cgit v1.2.3 From ea1e72277a264d69c2e4b9b15113dffcb6b7d662 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Sun, 11 Jun 2023 11:43:10 +0200 Subject: Ruptela IO Decoding for Device Temperature, Battery charging, Tow Alarm, Accident Alarm --- .../org/traccar/protocol/RuptelaProtocolDecoder.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 8672d104a..c9efd8f7b 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -108,6 +108,9 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 30: position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); break; + case 32: + position.set(Position.KEY_DEVICE_TEMP, readValue(buf, length, true)); + break; case 65: position.set(Position.KEY_ODOMETER, readValue(buf, length, true)); break; @@ -132,9 +135,22 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); } break; + case 170: + position.set(Position.KEY_CHARGE, readValue(buf, length, false) > 0); + break; case 197: position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); break; + case 410: + if (readValue(buf, length, false) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_TOW); + } + break; + case 411: + if (readValue(buf, length, false) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + } + break; case 645: position.set(Position.KEY_OBD_ODOMETER, readValue(buf, length, true) * 1000); break; -- cgit v1.2.3 From 873f08a8fd6e5e521e8c81421ebc2c3ea642ee52 Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Sun, 11 Jun 2023 13:30:48 +0300 Subject: Add increment value attribute on Duplicate Device Name for Route Report. Declaring uniqueSheetsTitle Add private method getUniqueSheetName Usage in getExcel sheetNames --- src/main/java/org/traccar/reports/RouteReportProvider.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 6d44259e6..bec1470bd 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -42,6 +42,9 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.Map; +import java.util.HashMap; +import java.util.concurrent.atomic.AtomicInteger; public class RouteReportProvider { @@ -66,7 +69,13 @@ public class RouteReportProvider { } return result; } + private final Map uniqueSheetsTitle = new HashMap<>(); + private String getUniqueSheetName(String key) { + AtomicInteger atomic = new AtomicInteger(uniqueSheetsTitle.getOrDefault(key, -1)); + uniqueSheetsTitle.put(key, atomic.incrementAndGet()); + return (uniqueSheetsTitle.get(key) > 0 ? key + "-" + uniqueSheetsTitle.get(key) : key); + } public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { @@ -78,7 +87,7 @@ public class RouteReportProvider { var positions = PositionUtil.getPositions(storage, device.getId(), from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); deviceRoutes.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); + sheetNames.add(WorkbookUtil.createSafeSheetName(getUniqueSheetName(deviceRoutes.getDeviceName()))); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( new Columns.All(), new Condition.Equals("id", device.getGroupId()))); -- cgit v1.2.3 From c98f4706e648e835ef7ac460e4a12381562515cd Mon Sep 17 00:00:00 2001 From: Nikolay Vlahovski Date: Sun, 11 Jun 2023 18:02:33 +0300 Subject: Refactor getUniqueSheetName in RouteReportProvider Rename uniqueSheetsTitle to namesCount Increase default namesCount counter to 1 Move namesCount to top --- src/main/java/org/traccar/reports/RouteReportProvider.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index bec1470bd..a1d004dd1 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -44,13 +44,13 @@ import java.util.Collection; import java.util.Date; import java.util.Map; import java.util.HashMap; -import java.util.concurrent.atomic.AtomicInteger; public class RouteReportProvider { private final Config config; private final ReportUtils reportUtils; private final Storage storage; + private final Map namesCount = new HashMap<>(); @Inject public RouteReportProvider(Config config, ReportUtils reportUtils, Storage storage) { @@ -69,12 +69,11 @@ public class RouteReportProvider { } return result; } - private final Map uniqueSheetsTitle = new HashMap<>(); + private String getUniqueSheetName(String key) { - AtomicInteger atomic = new AtomicInteger(uniqueSheetsTitle.getOrDefault(key, -1)); - uniqueSheetsTitle.put(key, atomic.incrementAndGet()); - return (uniqueSheetsTitle.get(key) > 0 ? key + "-" + uniqueSheetsTitle.get(key) : key); + namesCount.compute(key, (k, value) -> (value == null) ? 1 : (value + 1)); + return (namesCount.get(key) > 1 ? key + "-" + namesCount.get(key) : key); } public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, -- cgit v1.2.3 From 7f2ded68ef015684f90bef59c055a1c980688069 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 11 Jun 2023 08:10:16 -0700 Subject: Clean up formatting --- src/main/java/org/traccar/reports/RouteReportProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index a1d004dd1..5343652b7 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -50,6 +50,7 @@ public class RouteReportProvider { private final Config config; private final ReportUtils reportUtils; private final Storage storage; + private final Map namesCount = new HashMap<>(); @Inject @@ -72,9 +73,10 @@ public class RouteReportProvider { private String getUniqueSheetName(String key) { - namesCount.compute(key, (k, value) -> (value == null) ? 1 : (value + 1)); - return (namesCount.get(key) > 1 ? key + "-" + namesCount.get(key) : key); + namesCount.compute(key, (k, value) -> value == null ? 1 : (value + 1)); + return namesCount.get(key) > 1 ? key + '-' + namesCount.get(key) : key; } + public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { -- cgit v1.2.3 From f0aedd380e67488dfe73adf49f48a822ca4b232e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 11 Jun 2023 09:27:52 -0700 Subject: Additional VL502 parameters --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index ee5ab19d6..3adfa7daf 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -880,9 +880,15 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x0539: position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); break; + case 0x052B: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + break; case 0x052D: position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); break; + case 0x052E: + position.set("airTemp", buf.readUnsignedByte() - 40); + break; case 0x0530: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); break; @@ -892,6 +898,12 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x0536: position.set(Position.KEY_RPM, buf.readUnsignedShort()); break; + case 0x053D: + position.set("intakePressure", buf.readUnsignedShort() * 0.1); + break; + case 0x0544: + position.set("liquidLevel", buf.readUnsignedByte()); + break; case 0x0547: case 0x0548: position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); -- cgit v1.2.3 From 105e4b943e618d6fa8200d25225caeb4680c2080 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 16:49:33 +0200 Subject: Ruptela - saner ignition decoding --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 7 ++++--- traccar-web | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index c9efd8f7b..85f0d407a 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -99,9 +99,6 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 4: position.set("di" + (id - 1), readValue(buf, length, false)); break; - case 5: - position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); - break; case 29: position.set(Position.KEY_POWER, readValue(buf, length, false)); break; @@ -141,6 +138,10 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 197: position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); break; + case 251: + case 409: + position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); + break; case 410: if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_TOW); diff --git a/traccar-web b/traccar-web index f8048106d..877108d90 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit f8048106dacb36466ae221a8258da85f35db6e9d +Subproject commit 877108d9012301f2b149ae862af4cffe17dfb20d -- cgit v1.2.3 From 398128c7c3f7de283e9d35e74d96e4990381ef1b Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 17:10:01 +0200 Subject: Ruptela - motion, gps antenna alarm and inputs decoding improvements --- .../traccar/protocol/RuptelaProtocolDecoder.java | 21 +++++++++++++++++++++ traccar-web | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 85f0d407a..5fd7b755e 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -97,8 +97,21 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 2: case 3: case 4: + case 5: position.set("di" + (id - 1), readValue(buf, length, false)); break; + case 20: + position.set("ai3", readValue(buf, length, false)); + break; + case 21: + position.set("ai4", readValue(buf, length, false)); + break; + case 22: + position.set("ai1", readValue(buf, length, false)); + break; + case 23: + position.set("ai2", readValue(buf, length, false)); + break; case 29: position.set(Position.KEY_POWER, readValue(buf, length, false)); break; @@ -135,6 +148,9 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 170: position.set(Position.KEY_CHARGE, readValue(buf, length, false) > 0); break; + case 173: + position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + break; case 197: position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); break; @@ -152,6 +168,11 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); } break; + case 415: + if (readValue(buf, length, false) != 1) { + position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); + } + break; case 645: position.set(Position.KEY_OBD_ODOMETER, readValue(buf, length, true) * 1000); break; diff --git a/traccar-web b/traccar-web index 877108d90..cb7106f4b 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 877108d9012301f2b149ae862af4cffe17dfb20d +Subproject commit cb7106f4bfd6856470861890ea5e4c0bbc4703ac -- cgit v1.2.3 From 5ac55028cb315acec7e8f966c5ab11bdcc2c81bb Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 17:26:38 +0200 Subject: Ruptela - Tampering, Jamming and Network Operator decoding. --- .../java/org/traccar/protocol/RuptelaProtocolDecoder.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 5fd7b755e..2a552a874 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -132,6 +132,11 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 80: position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); break; + case 88: + if (readValue(buf, length, false) == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); + } + break; case 95: position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(readValue(buf, length, true))); break; @@ -145,6 +150,9 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); } break; + case 150: + position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); + break; case 170: position.set(Position.KEY_CHARGE, readValue(buf, length, false) > 0); break; @@ -176,6 +184,11 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 645: position.set(Position.KEY_OBD_ODOMETER, readValue(buf, length, true) * 1000); break; + case 758: + if (readValue(buf, length, false) == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); break; -- cgit v1.2.3 From acbb3b36fab3f03682f454c3a64a1a5c5bef4fd5 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 18:15:28 +0200 Subject: Ruptela - use > 0 for boolean comparison --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 2a552a874..d86476f9a 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -157,14 +157,14 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, readValue(buf, length, false) > 0); break; case 173: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + position.set(Position.KEY_MOTION, readValue(buf, length, false) > 0); break; case 197: position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); break; case 251: case 409: - position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); + position.set(Position.KEY_IGNITION, readValue(buf, length, false) > 0); break; case 410: if (readValue(buf, length, false) > 0) { -- cgit v1.2.3 From d6bc465b25f4be9c15342395c12fa73198da0842 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 19:33:56 +0200 Subject: Ruptela - correctly decode the input prefixes --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index d86476f9a..c1fc95e34 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -98,19 +98,19 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 3: case 4: case 5: - position.set("di" + (id - 1), readValue(buf, length, false)); + position.set(Position.PREFIX_IN + (id - 1), readValue(buf, length, false)); break; case 20: - position.set("ai3", readValue(buf, length, false)); + position.set(Position.PREFIX_ADC + 3, readValue(buf, length, false)); break; case 21: - position.set("ai4", readValue(buf, length, false)); + position.set(Position.PREFIX_ADC + 4, readValue(buf, length, false)); break; case 22: - position.set("ai1", readValue(buf, length, false)); + position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); break; case 23: - position.set("ai2", readValue(buf, length, false)); + position.set(Position.PREFIX_ADC + 2, readValue(buf, length, false)); break; case 29: position.set(Position.KEY_POWER, readValue(buf, length, false)); -- cgit v1.2.3 From 39ae0f3b25ba198c74a022bae059c45c4d0ac985 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 20:38:40 +0200 Subject: Ruptela - > 0 for boolean on the Jamming boolean --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index c1fc95e34..33372224b 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -133,7 +133,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); break; case 88: - if (readValue(buf, length, false) == 1) { + if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); } break; -- cgit v1.2.3 From f40a3307d7b77fd007572ee80ba3f0a0dd05cb51 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 22:22:50 +0200 Subject: Ruptela - only use GPS Antenna Cut Alarm when we know for sure that it's disconnected. --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 33372224b..737d30f10 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -177,7 +177,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } break; case 415: - if (readValue(buf, length, false) != 1) { + if (readValue(buf, length, false) == 0) { position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); } break; -- cgit v1.2.3 From 3ac7982d48bd7b3ed207a1461bc90a1cb7a888c4 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Mon, 12 Jun 2023 23:22:21 +0200 Subject: Ruptela - decode TCO Driver ID and BLE Beacon ID --- .../org/traccar/protocol/RuptelaProtocolDecoder.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 737d30f10..8a9bf21a4 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -285,6 +285,22 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { driverId.release(); } + Long tcoDriverIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 155); + Long tcoDriverIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 156); + if (tcoDriverIdPart1 != null && tcoDriverIdPart2 != null) { + ByteBuf driverId = Unpooled.copyLong(tcoDriverIdPart1, tcoDriverIdPart2); + position.set(Position.KEY_DRIVER_UNIQUE_ID, driverId.toString(StandardCharsets.US_ASCII)); + driverId.release(); + } + + Long bleBeaconIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 760); + Long bleBeaconIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 761); + if (bleBeaconIdPart1 != null && bleBeaconIdPart2 != null) { + ByteBuf bleBeaconId = Unpooled.copyLong(bleBeaconIdPart1, bleBeaconIdPart2); + position.set("bleBeaconId", bleBeaconId.toString(StandardCharsets.US_ASCII)); + bleBeaconId.release(); + } + positions.add(position); } -- cgit v1.2.3 From f1de2533c3527aefc6f9eb15277128bb8d8ec3cb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Jun 2023 21:57:27 -0700 Subject: Improve Watch frame decoder --- src/main/java/org/traccar/protocol/WatchFrameDecoder.java | 11 +++++++++-- src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchFrameDecoder.java b/src/main/java/org/traccar/protocol/WatchFrameDecoder.java index f99bd52e2..ec67aa34d 100644 --- a/src/main/java/org/traccar/protocol/WatchFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 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. @@ -27,7 +27,14 @@ public class WatchFrameDecoder extends BaseFrameDecoder { protected Object decode( ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ']') + 1; + int endIndex = -1; + for (int i = buf.writerIndex() - 1; i >= buf.readerIndex(); i--) { + if (buf.getByte(i) == ']') { + endIndex = i + 1; + break; + } + } + if (endIndex > 0) { ByteBuf frame = Unpooled.buffer(); while (buf.readerIndex() < endIndex) { diff --git a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java index 8b0486322..bf212544c 100644 --- a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java @@ -10,6 +10,10 @@ public class WatchFrameDecoderTest extends ProtocolTest { var decoder = inject(new WatchFrameDecoder()); + verifyFrame( + binary("5b33472a3838303930303234322a303133442a55442c3132303632332c3134303032302c412c34382e3934393237332c4e2c20342e333738333036302c452c31382e35362c34332e382c302e302c31322c3130302c37362c3232363132302c302c30303030303030302c322c3235352c3230342c382c333131302c35353032352c3134362c333133302c34393239372c3132342c352c42616e67696e67576966692c33343a61313a65643a65313a39313a34662c2d37312c42415220576946692c33363a61323a65313a65643a61313a64652c2d37322c4e6574776f726b576966692c32363a64653a61313a65643a65313a61302c2d37332c46696265722c33363a61313a65643a65313a39313a34662c2d37352c5b4c475f57616c6c2d4d6f756e7420412f435d653732352c36363a61313a65643a65313a65373a32352c2d38322c31352e305d"), + decoder.decode(null, null, binary("5b33472a3838303930303234322a303133442a55442c3132303632332c3134303032302c412c34382e3934393237332c4e2c20342e333738333036302c452c31382e35362c34332e382c302e302c31322c3130302c37362c3232363132302c302c30303030303030302c322c3235352c3230342c382c333131302c35353032352c3134362c333133302c34393239372c3132342c352c42616e67696e67576966692c33343a61313a65643a65313a39313a34662c2d37312c42415220576946692c33363a61323a65313a65643a61313a64652c2d37322c4e6574776f726b576966692c32363a64653a61313a65643a65313a61302c2d37332c46696265722c33363a61313a65643a65313a39313a34662c2d37352c5b4c475f57616c6c2d4d6f756e7420412f435d653732352c36363a61313a65643a65313a65373a32352c2d38322c31352e305d"))); + verifyFrame( binary("5b33472a3335323636313039303134333135302a303030412a4c4b2c302c302c3130305d"), decoder.decode(null, null, binary("5b33472a3335323636313039303134333135302a303030412a4c4b2c302c302c3130305d"))); -- cgit v1.2.3 From a3a086cfda4219815cba4ea6ca2cb44028c1e091 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 13 Jun 2023 13:37:24 +0200 Subject: Ruptela - tested bleBeaconID decoding --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 8a9bf21a4..2680e56b2 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -293,12 +293,10 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { driverId.release(); } - Long bleBeaconIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 760); - Long bleBeaconIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 761); - if (bleBeaconIdPart1 != null && bleBeaconIdPart2 != null) { - ByteBuf bleBeaconId = Unpooled.copyLong(bleBeaconIdPart1, bleBeaconIdPart2); - position.set("bleBeaconId", bleBeaconId.toString(StandardCharsets.US_ASCII)); - bleBeaconId.release(); + Long bleBeaconIdP1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 760); + Long bleBeaconIdP2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 761); + if (bleBeaconIdP1 != null && bleBeaconIdP2 != null) { + position.set("bleBeaconId", Long.toHexString(bleBeaconIdP1) + Long.toHexString(bleBeaconIdP2)); } positions.add(position); -- cgit v1.2.3 From cbfc5e524c98115ae0b1a4fb0754e9841a4fb915 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 13 Jun 2023 15:49:46 +0200 Subject: Ruptela renamed bleBeaconId to tagId --- .../org/traccar/protocol/RuptelaProtocolDecoder.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 2680e56b2..1f2887859 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -285,18 +285,18 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { driverId.release(); } - Long tcoDriverIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 155); - Long tcoDriverIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 156); - if (tcoDriverIdPart1 != null && tcoDriverIdPart2 != null) { - ByteBuf driverId = Unpooled.copyLong(tcoDriverIdPart1, tcoDriverIdPart2); + driverIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 155); + driverIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 156); + if (driverIdPart1 != null && driverIdPart2 != null) { + ByteBuf driverId = Unpooled.copyLong(driverIdPart1, driverIdPart2); position.set(Position.KEY_DRIVER_UNIQUE_ID, driverId.toString(StandardCharsets.US_ASCII)); driverId.release(); } - Long bleBeaconIdP1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 760); - Long bleBeaconIdP2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 761); - if (bleBeaconIdP1 != null && bleBeaconIdP2 != null) { - position.set("bleBeaconId", Long.toHexString(bleBeaconIdP1) + Long.toHexString(bleBeaconIdP2)); + Long tagIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 760); + Long tagIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 761); + if (tagIdPart1 != null && tagIdPart2 != null) { + position.set("tagId", Long.toHexString(tagIdPart1) + Long.toHexString(tagIdPart2)); } positions.add(position); -- cgit v1.2.3 From 262f8df7724966862482a5b1837462dad77ce074 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 13 Jun 2023 15:57:27 +0200 Subject: Ruptela restructure driver decoding --- .../traccar/protocol/RuptelaProtocolDecoder.java | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 1f2887859..2f127c70c 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -92,6 +92,16 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } } + private void decodeDriver(Position position, String part1, String part2) { + Long driverIdPart1 = (Long) position.getAttributes().remove(part1); + Long driverIdPart2 = (Long) position.getAttributes().remove(part2); + if (driverIdPart1 != null && driverIdPart2 != null) { + ByteBuf driverId = Unpooled.copyLong(driverIdPart1, driverIdPart2); + position.set(Position.KEY_DRIVER_UNIQUE_ID, driverId.toString(StandardCharsets.US_ASCII)); + driverId.release(); + } + } + private void decodeParameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 2: @@ -277,21 +287,11 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { decodeParameter(position, id, buf, 8); } - Long driverIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 126); - Long driverIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 127); - if (driverIdPart1 != null && driverIdPart2 != null) { - ByteBuf driverId = Unpooled.copyLong(driverIdPart1, driverIdPart2); - position.set(Position.KEY_DRIVER_UNIQUE_ID, driverId.toString(StandardCharsets.US_ASCII)); - driverId.release(); - } + // CAN first driver ID + decodeDriver(position, Position.PREFIX_IO + 126, Position.PREFIX_IO + 127); - driverIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 155); - driverIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 156); - if (driverIdPart1 != null && driverIdPart2 != null) { - ByteBuf driverId = Unpooled.copyLong(driverIdPart1, driverIdPart2); - position.set(Position.KEY_DRIVER_UNIQUE_ID, driverId.toString(StandardCharsets.US_ASCII)); - driverId.release(); - } + // TCO first driver ID + decodeDriver(position, Position.PREFIX_IO + 155, Position.PREFIX_IO + 156); Long tagIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 760); Long tagIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 761); -- cgit v1.2.3 From ea3ea7f53970817bf5dc2cf6b28f48f0836b3245 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 13 Jun 2023 16:51:30 +0200 Subject: Update src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 2f127c70c..1755ba8a8 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -287,11 +287,8 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { decodeParameter(position, id, buf, 8); } - // CAN first driver ID - decodeDriver(position, Position.PREFIX_IO + 126, Position.PREFIX_IO + 127); - - // TCO first driver ID - decodeDriver(position, Position.PREFIX_IO + 155, Position.PREFIX_IO + 156); + decodeDriver(position, Position.PREFIX_IO + 126, Position.PREFIX_IO + 127); // can driver + decodeDriver(position, Position.PREFIX_IO + 155, Position.PREFIX_IO + 156); // tco driver Long tagIdPart1 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 760); Long tagIdPart2 = (Long) position.getAttributes().remove(Position.PREFIX_IO + 761); -- cgit v1.2.3 From 94fbc93f8b0a75fe17e529355c4e7758b81b4776 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Jun 2023 22:21:18 -0700 Subject: Additional Atrack parameters --- .../org/traccar/protocol/AtrackProtocolDecoder.java | 17 +++++++++++++++++ .../org/traccar/protocol/AtrackProtocolDecoderTest.java | 3 +++ 2 files changed, 20 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index aa19e9e41..8896dcfb0 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -614,6 +614,23 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { case "JN5": buf.readUnsignedInt(); // pto fuel break; + case "IN0": + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + break; + case "IN1": + case "IN2": + case "IN3": + position.set(Position.PREFIX_IN + key.charAt(2), buf.readUnsignedByte() > 0); + break; + case "HA": + position.set(Position.KEY_ALARM, buf.readUnsignedByte() > 0 ? Position.ALARM_ACCELERATION : null); + break; + case "HB": + position.set(Position.KEY_ALARM, buf.readUnsignedByte() > 0 ? Position.ALARM_BRAKING : null); + break; + case "HC": + position.set(Position.KEY_ALARM, buf.readUnsignedByte() > 0 ? Position.ALARM_CORNERING : null); + break; default: break; } diff --git a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java index 32000c4a7..be6fb5c45 100644 --- a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -43,6 +43,9 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { decoder.setCustom(true); + verifyPositions(decoder, binary( + "4050d78502e01d29000312fa45441d6d647d8e67647d8e67647eef190205437c021846e6001a020002d7f000070000000000000007d007d000254349254d5625525025564e254d4625454c25545225455425464c254d4c25464325534d25494e3025484125484225484325415400010c0000000000000000000000000000000000000000000000000e647d8e85647d8e86647eef190205437c021846e60019020002d7f000070000000000000007d007d000254349254d5625525025564e254d4625454c25545225455425464c254d4c25464325534d25494e3025484125484225484325415400010c0000000000000000000000000000000000000000000000000e647d8ea3647d8ea4647eef190205437c021846e60019020002d7f000070000000000000007d007d000254349254d5625525025564e254d4625454c25545225455425464c254d4c25464325534d25494e3025484125484225484325415400010b0000000000000000000000000000000000000000000000000e647d8ec1647d8ec2647eef190205437c021846e60019020002d7f000070000000000000007d007d000254349254d5625525025564e254d4625454c25545225455425464c254d4c25464325534d25494e3025484125484225484325415400010a0000000000000000000000000000000000000000000000000e647d8edf647d8ee0647eef190205437c021846e60019020002d7f000070000000000000007d007d000254349254d5625525025564e254d4625454c25545225455425464c254d4c25464325534d25494e3025484125484225484325415400010a0000000000000000000000000000000000000000000000000e647d8efd647d8efe647eef190205437c021846e60019020002d7f000070000000000000007d007d000254349254d5625525025564e254d4625454c25545225455425464c254d4c25464325534d25494e3025484125484225484325415400010a0000000000000000000000000000000000000000000000000e")); + verifyPositions(decoder, binary( "405099280272000300014399e3f93d136438abdf644083f56440842afb2711c701b9eaee0067020003e0bb03de0000000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c3400000000000000000000000000000000000000000000930025000000000000000000000000000000006438abdf644083f76440842afb2711c701b9eaee0067710003e0bb03de0100000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c3400000000000000000000000000000000000000000000950025000000000000000000000000000000006438abdf644083f76440842afb2711c701b9eaee0067840003e0bb03de0100000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c3400000000000000000000000000000000000000000000950025000000000000000000000000000000006438abdf644083f86440842afb2711c701b9eaee0067760003e0bb03de0100000000000007d007d00025434925454c25455425464325464c255250254d4c25534d25545225494125454f25564e254d56254256254548255a4c33255a4f3134255a4f3131255a4f3130255a4f32255a4c340000000000000000000000000000000000000000000095002500000000000000000000000000000000")); -- cgit v1.2.3 From 03650fff8064b60ffcda75f9033fd44e66ef34b3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 15 Jun 2023 05:35:09 -0700 Subject: Galileo Iridium frame decoding --- .../java/org/traccar/protocol/GalileoFrameDecoder.java | 16 +++++++++++----- .../org/traccar/protocol/GalileoFrameDecoderTest.java | 4 ++++ 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GalileoFrameDecoder.java b/src/main/java/org/traccar/protocol/GalileoFrameDecoder.java index c23d26c83..d90e48287 100644 --- a/src/main/java/org/traccar/protocol/GalileoFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -22,7 +22,7 @@ import org.traccar.BaseFrameDecoder; public class GalileoFrameDecoder extends BaseFrameDecoder { - private static final int MESSAGE_MINIMUM_LENGTH = 5; + private static final int MESSAGE_MINIMUM_LENGTH = 6; @Override protected Object decode( @@ -32,9 +32,15 @@ public class GalileoFrameDecoder extends BaseFrameDecoder { return null; } - int length = buf.getUnsignedShortLE(buf.readerIndex() + 1) & 0x7fff; - if (buf.readableBytes() >= (length + MESSAGE_MINIMUM_LENGTH)) { - return buf.readRetainedSlice(length + MESSAGE_MINIMUM_LENGTH); + int length; + if (buf.getByte(buf.readerIndex()) == 0x01 && buf.getUnsignedMedium(buf.readerIndex() + 3) == 0x01001c) { + length = 3 + buf.getUnsignedShort(buf.readerIndex() + 1); + } else { + length = 5 + (buf.getUnsignedShortLE(buf.readerIndex() + 1) & 0x7fff); + } + + if (buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); } return null; diff --git a/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java index 256517460..530f0930e 100644 --- a/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java @@ -12,6 +12,10 @@ public class GalileoFrameDecoderTest extends ProtocolTest { var decoder = inject(new GalileoFrameDecoder()); + assertEquals( + binary("01003f01001c475b166133303035333430363431383437393000001d000064897bb003000b0221c20512a60a0000000802000f209d7b8964300f2536fbfd103c1d01"), + decoder.decode(null, null, binary("01003f01001c475b166133303035333430363431383437393000001d000064897bb003000b0221c20512a60a0000000802000f209d7b8964300f2536fbfd103c1d01"))); + assertEquals( binary("011780011102e603383633353931303238393630323437043200801c"), decoder.decode(null, null, binary("011780011102e603383633353931303238393630323437043200801c"))); -- cgit v1.2.3 From 4a64ef748e207406be4f7aa7538d59b7b0f9735c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 15 Jun 2023 05:53:04 -0700 Subject: Decode JT808 battery level --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 6 ++++++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 3adfa7daf..beb1ec41a 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -484,6 +484,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, Integer.parseInt(lockStatus.substring(2, 5)) * 0.01); } break; + case 0x56: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 10); + buf.readUnsignedByte(); // reserved + break; case 0x60: position.set(Position.KEY_EVENT, buf.readUnsignedShort()); buf.skipBytes(length - 2); @@ -692,6 +696,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0xFE: if (length == 1) { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } else if (length == 2) { + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); } else { int mark = buf.readUnsignedByte(); if (mark == 0x7C) { diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 5fd9ed894..9c3fc164a 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( + "7e0200003f014501643822000300020000000c000c0000000000000000000000000000230615143903300111310100530901027f0300456f073e56020900fe02001e57080002000200000000df7e"), + Position.KEY_BATTERY_LEVEL, 90); + verifyAttribute(decoder, binary( "7e090000344f07788ef87d0138f02305151230460102020001ffffffff000100001457000000020006503134353700000c000a029dc63004b99a98230515132726787e"), Position.KEY_DTCS, "P1457"); -- cgit v1.2.3 From e7ca96d67650f0d8059983ff63c6ea31b562b481 Mon Sep 17 00:00:00 2001 From: memesaregood Date: Thu, 15 Jun 2023 17:01:34 +0300 Subject: Allowed primitive Java types in JEXL Engine --- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index d384bbffc..24d853bbe 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -65,6 +65,14 @@ public class ComputedAttributesHandler extends BaseDataHandler { JexlSandbox sandbox = new JexlSandbox(false); sandbox.allow("com.safe.Functions"); sandbox.allow(Math.class.getName()); + sandbox.allow(Double.class.getName()); + sandbox.allow(Float.class.getName()); + sandbox.allow(Integer.class.getName()); + sandbox.allow(Long.class.getName()); + sandbox.allow(Short.class.getName()); + sandbox.allow(Character.class.getName()); + sandbox.allow(Boolean.class.getName()); + sandbox.allow(String.class.getName()); features = new JexlFeatures() .localVar(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES)) .loops(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS)) -- cgit v1.2.3 From 57414098b8295e91d9c2436cf4be18c0ef430fd3 Mon Sep 17 00:00:00 2001 From: memesaregood Date: Thu, 15 Jun 2023 17:55:28 +0300 Subject: Use a lambda expression to allow the primitive types --- .../java/org/traccar/handler/ComputedAttributesHandler.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 24d853bbe..29d9bcdcb 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.List; import io.netty.channel.ChannelHandler; import org.apache.commons.jexl3.JexlFeatures; @@ -65,14 +66,10 @@ public class ComputedAttributesHandler extends BaseDataHandler { JexlSandbox sandbox = new JexlSandbox(false); sandbox.allow("com.safe.Functions"); sandbox.allow(Math.class.getName()); - sandbox.allow(Double.class.getName()); - sandbox.allow(Float.class.getName()); - sandbox.allow(Integer.class.getName()); - sandbox.allow(Long.class.getName()); - sandbox.allow(Short.class.getName()); - sandbox.allow(Character.class.getName()); - sandbox.allow(Boolean.class.getName()); - sandbox.allow(String.class.getName()); + List.of(Double.class, Float.class, Integer.class, + Long.class, Short.class, Character.class, + Boolean.class, String.class, Byte.class) + .forEach((type) -> sandbox.allow(type.getName())); features = new JexlFeatures() .localVar(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES)) .loops(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOOPS)) -- cgit v1.2.3 From 2275e7d4e739eab9e24eab66d068cf0afafc5bb8 Mon Sep 17 00:00:00 2001 From: memesaregood1 <63505425+memesaregood1@users.noreply.github.com> Date: Thu, 15 Jun 2023 21:09:50 +0300 Subject: Update src/main/java/org/traccar/handler/ComputedAttributesHandler.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 29d9bcdcb..8ad4e41e4 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -66,9 +66,9 @@ public class ComputedAttributesHandler extends BaseDataHandler { JexlSandbox sandbox = new JexlSandbox(false); sandbox.allow("com.safe.Functions"); sandbox.allow(Math.class.getName()); - List.of(Double.class, Float.class, Integer.class, - Long.class, Short.class, Character.class, - Boolean.class, String.class, Byte.class) + List.of( + Double.class, Float.class, Integer.class, Long.class, Short.class, + Character.class, Boolean.class, String.class, Byte.class) .forEach((type) -> sandbox.allow(type.getName())); features = new JexlFeatures() .localVar(config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_LOCAL_VARIABLES)) -- cgit v1.2.3 From 8ee2199cff0596790111e5ead43ec3da29a440dc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Jun 2023 07:00:57 -0700 Subject: Do not count service account --- src/main/java/org/traccar/database/StatisticsManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index e0995dabc..c8a36bf78 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.api.security.ServiceAccountUser; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DateUtil; @@ -147,7 +148,7 @@ public class StatisticsManager { public synchronized void registerRequest(long userId) { checkSplit(); requests += 1; - if (userId != 0) { + if (userId != 0 && userId != ServiceAccountUser.ID) { users.add(userId); } } -- cgit v1.2.3 From ef99a5067522d5affcd0550eb299e37c916e3096 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Jun 2023 07:41:43 -0700 Subject: Add daily limit filter --- src/main/java/org/traccar/config/Keys.java | 7 +++++++ src/main/java/org/traccar/database/StatisticsManager.java | 7 +++++++ src/main/java/org/traccar/handler/FilterHandler.java | 15 ++++++++++++++- src/test/java/org/traccar/handler/FilterHandlerTest.java | 4 ++-- 4 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 1ff1d1b51..04bf10fe7 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1327,6 +1327,13 @@ public final class Keys { "filter.minPeriod", List.of(KeyType.CONFIG)); + /** + * Filter position if the daily limit is exceeded for the device. + */ + public static final ConfigKey FILTER_DAILY_LIMIT = new IntegerConfigKey( + "filter.dailyLimit", + List.of(KeyType.CONFIG)); + /** * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, * distance, speed, or time period only against the location that was last received by server. diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index c8a36bf78..e417c8901 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -58,6 +58,7 @@ public class StatisticsManager { private final Set users = new HashSet<>(); private final Map deviceProtocols = new HashMap<>(); + private final Map deviceMessages = new HashMap<>(); private int requests; private int messagesReceived; @@ -101,6 +102,7 @@ public class StatisticsManager { users.clear(); deviceProtocols.clear(); + deviceMessages.clear(); requests = 0; messagesReceived = 0; messagesStored = 0; @@ -163,9 +165,14 @@ public class StatisticsManager { messagesStored += 1; if (deviceId != 0) { deviceProtocols.put(deviceId, protocol); + deviceMessages.merge(deviceId, 1, Integer::sum); } } + public synchronized int messageStoredCount(long deviceId) { + return deviceMessages.getOrDefault(deviceId, 0); + } + public synchronized void registerMail() { checkSplit(); mailSent += 1; diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 9ff94deb0..37c3beddf 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Device; @@ -57,15 +58,18 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { private final int filterDistance; private final int filterMaxSpeed; private final long filterMinPeriod; + private final int filterDailyLimit; private final boolean filterRelative; private final long skipLimit; private final boolean skipAttributes; private final CacheManager cacheManager; private final Storage storage; + private final StatisticsManager statisticsManager; @Inject - public FilterHandler(Config config, CacheManager cacheManager, Storage storage) { + public FilterHandler( + Config config, CacheManager cacheManager, Storage storage, StatisticsManager statisticsManager) { enabled = config.getBoolean(Keys.FILTER_ENABLE); filterInvalid = config.getBoolean(Keys.FILTER_INVALID); filterZero = config.getBoolean(Keys.FILTER_ZERO); @@ -79,11 +83,13 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { filterDistance = config.getInteger(Keys.FILTER_DISTANCE); filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED); filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000L; + filterDailyLimit = config.getInteger(Keys.FILTER_DAILY_LIMIT); filterRelative = config.getBoolean(Keys.FILTER_RELATIVE); skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000; skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE); this.cacheManager = cacheManager; this.storage = storage; + this.statisticsManager = statisticsManager; } private Position getPrecedingPosition(long deviceId, Date date) throws StorageException { @@ -165,6 +171,13 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { return false; } + private boolean filterDailyLimit(Position position) { + if (filterDailyLimit != 0) { + return statisticsManager.messageStoredCount(position.getDeviceId()) >= filterDailyLimit; + } + return false; + } + private boolean skipLimit(Position position, Position last) { if (skipLimit != 0 && last != null) { return (position.getServerTime().getTime() - last.getServerTime().getTime()) > skipLimit; diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java index 26281e351..14037f723 100644 --- a/src/test/java/org/traccar/handler/FilterHandlerTest.java +++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java @@ -29,7 +29,7 @@ public class FilterHandlerTest extends BaseTest { when(config.getBoolean(Keys.FILTER_ENABLE)).thenReturn(true); var cacheManager = mock(CacheManager.class); when(cacheManager.getConfig()).thenReturn(config); - passingHandler = new FilterHandler(config, cacheManager, null); + passingHandler = new FilterHandler(config, cacheManager, null, null); } @BeforeEach @@ -50,7 +50,7 @@ public class FilterHandlerTest extends BaseTest { var cacheManager = mock(CacheManager.class); when(cacheManager.getConfig()).thenReturn(config); when(cacheManager.getObject(any(), anyLong())).thenReturn(mock(Device.class)); - filteringHandler = new FilterHandler(config, cacheManager, null); + filteringHandler = new FilterHandler(config, cacheManager, null, null); } private Position createPosition(Date time, boolean valid, double speed) { -- cgit v1.2.3 From ba8191373d55d6115427ef7187b8f2d0650a5ec5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Jun 2023 07:47:58 -0700 Subject: Apply the filter --- src/main/java/org/traccar/handler/FilterHandler.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 37c3beddf..2623c3486 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -223,6 +223,9 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { if (filterApproximate(position)) { filterType.append("Approximate "); } + if (filterDailyLimit(position)) { + filterType.append("DailyLimit "); + } // filter out excessive data long deviceId = position.getDeviceId(); -- cgit v1.2.3 From a2c35b1c98a56d07924f955bb6d4172f27623816 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 20 Jun 2023 08:35:49 -0700 Subject: Decode Eview status bits --- .../java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index f660f2e92..f8b0c34e9 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -239,6 +239,14 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { case 0x24: position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); long status = buf.readUnsignedIntLE(); + if (BitUtil.check(status, 4)) { + position.set(Position.KEY_CHARGE, true); + } + if (BitUtil.check(status, 7)) { + position.set(Position.KEY_ARCHIVE, true); + } + position.set(Position.KEY_MOTION, BitUtil.check(status, 9)); + position.set(Position.KEY_RSSI, BitUtil.between(status, 19, 24)); position.set(Position.KEY_BATTERY_LEVEL, BitUtil.from(status, 24)); position.set(Position.KEY_STATUS, status); break; -- cgit v1.2.3 From a3b03c7744a6767cede6725ba7089823e11b983a Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 21 Jun 2023 00:18:46 +0200 Subject: Ruptela Decoder - implement Extended protocol extended messages merging --- .../java/org/traccar/protocol/RuptelaProtocolDecoder.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 1755ba8a8..294768860 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -236,7 +236,18 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // timestamp extension if (type == MSG_EXTENDED_RECORDS) { - buf.readUnsignedByte(); // record extension + int b = buf.readUnsignedByte(); // record extension + int noRecordsToMerge = (b & 0xf0) >> 4; + int currentRecord = b & 0x0f; + + if (currentRecord > 0 && noRecordsToMerge >= currentRecord) { + if (!positions.isEmpty() + && positions.get(positions.size() - 1).getDeviceTime() + .compareTo(position.getDeviceTime()) == 0) { + position = positions.remove(positions.size() - 1); + } + } + } buf.readUnsignedByte(); // priority (reserved) -- cgit v1.2.3 From b8e9d39d711c0d9f2af26aa90bfb167af364a8d3 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 21 Jun 2023 12:00:52 +0200 Subject: Ruptela Decoder use Bitutil for record extension merging --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 294768860..ecb5c4204 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -22,6 +22,7 @@ import org.traccar.BaseProtocolDecoder; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.helper.BitUtil; import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -236,9 +237,9 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // timestamp extension if (type == MSG_EXTENDED_RECORDS) { - int b = buf.readUnsignedByte(); // record extension - int noRecordsToMerge = (b & 0xf0) >> 4; - int currentRecord = b & 0x0f; + int recordExtension = buf.readUnsignedByte(); // record extension + int noRecordsToMerge = BitUtil.between(recordExtension, 4, 8); + int currentRecord = BitUtil.to(recordExtension, 4); if (currentRecord > 0 && noRecordsToMerge >= currentRecord) { if (!positions.isEmpty() @@ -247,7 +248,6 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position = positions.remove(positions.size() - 1); } } - } buf.readUnsignedByte(); // priority (reserved) -- cgit v1.2.3 From 149db397ce7bbf60834260a7585366e515c8de24 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 21 Jun 2023 12:08:23 +0200 Subject: Ruptela Decoder - power factor standardization --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index ecb5c4204..1d627c5f3 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -124,7 +124,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 2, readValue(buf, length, false)); break; case 29: - position.set(Position.KEY_POWER, readValue(buf, length, false)); + position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); break; case 30: position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); -- cgit v1.2.3 From 5ee370870401ae2e18a477d01f22128c6109f015 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 21 Jun 2023 19:11:40 +0200 Subject: Update src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 1d627c5f3..79e8e1091 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -241,7 +241,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { int noRecordsToMerge = BitUtil.between(recordExtension, 4, 8); int currentRecord = BitUtil.to(recordExtension, 4); - if (currentRecord > 0 && noRecordsToMerge >= currentRecord) { + if (currentRecord > 0 && currentRecord <= noRecordsToMerge) { if (!positions.isEmpty() && positions.get(positions.size() - 1).getDeviceTime() .compareTo(position.getDeviceTime()) == 0) { -- cgit v1.2.3 From 648e7f652a5ca1024813864b2dea2572c9f5e3f0 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 21 Jun 2023 19:12:09 +0200 Subject: Update src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 79e8e1091..a8296771a 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -237,7 +237,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // timestamp extension if (type == MSG_EXTENDED_RECORDS) { - int recordExtension = buf.readUnsignedByte(); // record extension + int recordExtension = buf.readUnsignedByte(); int noRecordsToMerge = BitUtil.between(recordExtension, 4, 8); int currentRecord = BitUtil.to(recordExtension, 4); -- cgit v1.2.3 From e43d353b7cc0f2bf34a77d58529c1360683d81c1 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 21 Jun 2023 19:15:44 +0200 Subject: Ruptela Decoder - extended records merging, remove redudant checks and better variable naming --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index a8296771a..d067d2ddc 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -238,15 +238,11 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_EXTENDED_RECORDS) { int recordExtension = buf.readUnsignedByte(); - int noRecordsToMerge = BitUtil.between(recordExtension, 4, 8); + int mergeRecordCount = BitUtil.between(recordExtension, 4, 8); int currentRecord = BitUtil.to(recordExtension, 4); - if (currentRecord > 0 && currentRecord <= noRecordsToMerge) { - if (!positions.isEmpty() - && positions.get(positions.size() - 1).getDeviceTime() - .compareTo(position.getDeviceTime()) == 0) { - position = positions.remove(positions.size() - 1); - } + if (currentRecord > 0 && currentRecord <= mergeRecordCount) { + position = positions.remove(positions.size() - 1); } } -- cgit v1.2.3 From eccbcfdd6906979763d0825f2b112a3050343381 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 21 Jun 2023 19:48:25 +0200 Subject: Update src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index d067d2ddc..2122d5081 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -238,7 +238,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_EXTENDED_RECORDS) { int recordExtension = buf.readUnsignedByte(); - int mergeRecordCount = BitUtil.between(recordExtension, 4, 8); + int mergeRecordCount = BitUtil.from(recordExtension, 4); int currentRecord = BitUtil.to(recordExtension, 4); if (currentRecord > 0 && currentRecord <= mergeRecordCount) { -- cgit v1.2.3 From d2909b90af2344176d2018bdbb2f410ea6e44465 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 22 Jun 2023 06:41:05 -0700 Subject: Decode Fifotrack engine hours --- src/main/java/org/traccar/model/Position.java | 2 +- src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 3ed340703..6685cab95 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -42,7 +42,7 @@ public class Position extends Message { public static final String KEY_ODOMETER = "odometer"; // meters public static final String KEY_ODOMETER_SERVICE = "serviceOdometer"; // meters public static final String KEY_ODOMETER_TRIP = "tripOdometer"; // meters - public static final String KEY_HOURS = "hours"; + public static final String KEY_HOURS = "hours"; // milliseconds public static final String KEY_STEPS = "steps"; public static final String KEY_HEART_RATE = "heartRate"; public static final String KEY_INPUT = "input"; diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index e0dd1d62d..14b33b67f 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -64,7 +64,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // course .number("(-?d+),") // altitude .number("(d+),") // odometer - .number("d+,") // runtime + .number("(d+),") // engine hours .number("(x+),") // status .number("(x+)?,") // input .number("(x+)?,") // output @@ -290,6 +290,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(parser.nextInt()); position.set(Position.KEY_ODOMETER, parser.nextLong()); + position.set(Position.KEY_HOURS, parser.nextLong() * 1000); long status = parser.nextHexLong(); position.set(Position.KEY_RSSI, BitUtil.between(status, 3, 8)); -- cgit v1.2.3 From 2088a59da55e581391f9a768003b68baca467007 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Jun 2023 07:21:23 -0700 Subject: Xexun2 signed signal strength --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 913dfaf28..46e3dd118 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -164,7 +164,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < cellCount; j++) { network.addCellTower(CellTower.from( buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readInt(), buf.readUnsignedInt(), buf.readUnsignedByte())); + buf.readInt(), buf.readUnsignedInt(), buf.readByte())); } } if (network.getWifiAccessPoints() != null || network.getCellTowers() != null) { -- cgit v1.2.3 From 3b6900a95342ae87861cfcae8870ac790da7a504 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Jun 2023 22:33:54 -0700 Subject: Support services message type --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 2 +- .../java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index f8b0c34e9..cd8d8e0cf 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -151,7 +151,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, remoteAddress, index, type, buf); } - if (type == MSG_DATA) { + if (type == MSG_DATA || type == MSG_SERVICES) { List positions = new LinkedList<>(); Set keys = new HashSet<>(); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index 693a11fc5..587a520d1 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -24,10 +24,10 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "ab10350015ae59010110013836333932313033333836353231360924723a12610042535a182ac0f6b4f2923100c900af02215c2b9bfb5461736b4c4d53")); - verifyNull(decoder, binary( + verifyPositions(decoder, false, binary( "ab10150076f1320003100133353534363530373130323933303602105a")); - verifyNull(decoder, binary( + verifyPositions(decoder, false, binary( "AB101400594A01000310013836333932323033343437333734350112")); verifyPositions(decoder, binary( -- cgit v1.2.3 From 1b899329364619cbdc4213e2fd065955a94f5c6c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Jun 2023 22:39:23 -0700 Subject: Fix Fifotrack Q2 decoding --- src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 14b33b67f..c30398d36 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -235,8 +235,8 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { position.setValid(parser.next().equals("A")); position.setFixTime(position.getDeviceTime()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.set(Position.KEY_SATELLITES, parser.nextInt()); position.setLatitude(parser.nextDouble()); position.setLongitude(parser.nextDouble()); diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java index 518eada52..cbfc46703 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new FifotrackProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "$$99,865413050150407,7F,A03,,230626072722,460|0|25FC|AC2AB0B,3.74,52,0019,0,A,0,13,22.643466,114.018211*74"), + Position.KEY_SATELLITES, 13); + verifyPosition(decoder, buffer( "$$95,866104023192332,1,A03,,210414055249,460|0|25FC|104C,4.18,100,000F,0,A,2,9,22.643175,114.018150*75")); -- cgit v1.2.3 From 3952b3445d96d91f87d6a427ba10a86907cb0fea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Jun 2023 22:43:06 -0700 Subject: Fix Xexun2 wifi signal --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 46e3dd118..0e3c44e12 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -156,7 +156,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < wifiCount; j++) { String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + mac.substring(0, mac.length() - 1), buf.readByte())); } } if (BitUtil.check(positionMask, 2)) { -- cgit v1.2.3 From bc99846b0c88ac41b96744edd23ef254f492c0b7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Jun 2023 23:01:42 -0700 Subject: Support HWDECO fuel sensor --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 48 ++++++++++++++++++++++ .../protocol/Gl200TextProtocolDecoderTest.java | 4 ++ 2 files changed, 52 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 0135e78b7..bcff1c5b2 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -15,7 +15,9 @@ */ package org.traccar.protocol; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.DataConverter; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -368,6 +370,21 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_DTT = new PatternBuilder() + .text("+RESP:GTDTT,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,,,") // device name + .number("d,") // data type + .number("d+,") // data length + .number("(x+),") // data + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF):GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -1165,6 +1182,34 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeDtt(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_DTT, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + getLastLocation(position, null); + + /* + Ecuatrack +COMB,0,94.0,-1.0,,,HDC + */ + + String data = Unpooled.wrappedBuffer(DataConverter.parseHex(parser.next())) + .toString(StandardCharsets.US_ASCII); + if (data.contains("COMB")) { + String[] values = data.split(","); + position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(values[2])); + } else { + position.set(Position.KEY_RESULT, data); + } + + decodeDeviceTime(position, parser); + + return position; + } + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { Parser parser = new Parser(PATTERN, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1359,6 +1404,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "DAR": result = decodeDar(channel, remoteAddress, sentence); break; + case "DTT": + result = decodeDtt(channel, remoteAddress, sentence); + break; default: result = decodeOther(channel, remoteAddress, sentence, type); break; diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index a73127546..760671cd9 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "+RESP:GTDTT,410502,864802030541621,,,,1,35,45637561747261636b0d0a434f4d422c302c39342e302c2d312e302c2c2c4844430d0a,20230421034626,EA2E$"), + Position.KEY_FUEL_LEVEL, 94.0); + verifyNull(decoder, buffer( "+RESP:GTFRI,5E0100,862061048023666,,,12940,10,1,1,0.0,97,179.8,-90.366478,38.735379,20230616183231,0310,0410,6709,03ADF710,00,6223.7,,,,,110000,,,,202306161834$")); -- cgit v1.2.3 From a19356db10b62592a565d5a073ee989e299a0aa1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Jun 2023 23:04:50 -0700 Subject: Remove sample data comment --- src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index bcff1c5b2..a0e217165 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -1191,11 +1191,6 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - /* - Ecuatrack -COMB,0,94.0,-1.0,,,HDC - */ - String data = Unpooled.wrappedBuffer(DataConverter.parseHex(parser.next())) .toString(StandardCharsets.US_ASCII); if (data.contains("COMB")) { -- cgit v1.2.3 From 37564d458bb9d4bca9f1634bbe07e1102e0221cd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 1 Jul 2023 07:56:59 -0700 Subject: No override for API path --- src/main/java/org/traccar/web/OverrideFilter.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java index 70eb80a67..6d20789f2 100644 --- a/src/main/java/org/traccar/web/OverrideFilter.java +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -45,6 +45,11 @@ public class OverrideFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + if (((HttpServletRequest) request).getServletPath().startsWith("/api")) { + chain.doFilter(request, response); + return; + } + ResponseWrapper wrappedResponse = new ResponseWrapper((HttpServletResponse) response); chain.doFilter(request, wrappedResponse); -- cgit v1.2.3 From 7c5df536074e850f8f9e35775ca94fd04c3cdd3a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 1 Jul 2023 13:32:03 -0700 Subject: Configurable API timeout --- src/main/java/org/traccar/config/Keys.java | 8 ++++++++ src/main/java/org/traccar/web/ThrottlingFilter.java | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 04bf10fe7..e171511e6 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -738,6 +738,14 @@ public final class Keys { "web.maxRequestsPerSec", List.of(KeyType.CONFIG)); + /** + * Maximum API request duration in seconds. + */ + public static final ConfigKey WEB_MAX_REQUEST_SECONDS = new IntegerConfigKey( + "web.maxRequestSec", + List.of(KeyType.CONFIG), + 600); + /** * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based * interface doesn't require this. diff --git a/src/main/java/org/traccar/web/ThrottlingFilter.java b/src/main/java/org/traccar/web/ThrottlingFilter.java index 054af652f..6d2328562 100644 --- a/src/main/java/org/traccar/web/ThrottlingFilter.java +++ b/src/main/java/org/traccar/web/ThrottlingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -39,6 +39,7 @@ public class ThrottlingFilter extends DoSFilter { if (config.hasKey(Keys.WEB_MAX_REQUESTS_PER_SECOND)) { setMaxRequestsPerSec(config.getInteger(Keys.WEB_MAX_REQUESTS_PER_SECOND)); } + setMaxRequestMs(config.getInteger(Keys.WEB_MAX_REQUEST_SECONDS) * 1000L); } @Override -- cgit v1.2.3 From cad2b8497c7cbd2cde4e50ec1ce2af1ceb37d02c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 1 Jul 2023 14:57:03 -0700 Subject: Support XML-based SMS APIs --- src/main/java/org/traccar/sms/HttpSmsClient.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/sms/HttpSmsClient.java b/src/main/java/org/traccar/sms/HttpSmsClient.java index 683022967..b4271a6f2 100644 --- a/src/main/java/org/traccar/sms/HttpSmsClient.java +++ b/src/main/java/org/traccar/sms/HttpSmsClient.java @@ -57,7 +57,10 @@ public class HttpSmsClient implements SmsManager { } } template = config.getString(Keys.SMS_HTTP_TEMPLATE).trim(); - if (template.charAt(0) == '{' || template.charAt(0) == '[') { + if (template.charAt(0) == '<') { + encode = false; + mediaType = MediaType.APPLICATION_XML_TYPE; + } else if (template.charAt(0) == '{' || template.charAt(0) == '[') { encode = false; mediaType = MediaType.APPLICATION_JSON_TYPE; } else { -- cgit v1.2.3 From 914cc6e85ba8696727edff2d8a600ae695bc410d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 1 Jul 2023 16:04:07 -0700 Subject: Add calendar based filtering --- schema/changelog-5.9.xml | 27 +++++++++++++++++++ schema/changelog-master.xml | 1 + .../traccar/api/security/PermissionsService.java | 12 ++++----- .../java/org/traccar/handler/FilterHandler.java | 12 +++++++-- src/main/java/org/traccar/model/Device.java | 16 ++++++++++-- src/main/java/org/traccar/model/Geofence.java | 16 ++++++++++-- src/main/java/org/traccar/model/Notification.java | 14 +++++++++- src/main/java/org/traccar/model/Report.java | 16 ++++++++++-- src/main/java/org/traccar/model/Schedulable.java | 22 ++++++++++++++++ .../java/org/traccar/model/ScheduledModel.java | 30 ---------------------- .../org/traccar/session/cache/CacheManager.java | 27 ++++++++++--------- 11 files changed, 136 insertions(+), 57 deletions(-) create mode 100644 schema/changelog-5.9.xml create mode 100644 src/main/java/org/traccar/model/Schedulable.java delete mode 100644 src/main/java/org/traccar/model/ScheduledModel.java (limited to 'src/main/java/org') diff --git a/schema/changelog-5.9.xml b/schema/changelog-5.9.xml new file mode 100644 index 000000000..50a3d3aaa --- /dev/null +++ b/schema/changelog-5.9.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index dd2bcc8a7..331d5ec78 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -39,5 +39,6 @@ + diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 18a376601..38bf48f30 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -24,7 +24,7 @@ import org.traccar.model.Group; import org.traccar.model.GroupedModel; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; -import org.traccar.model.ScheduledModel; +import org.traccar.model.Schedulable; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.model.UserRestrictions; @@ -137,13 +137,13 @@ public class PermissionsService { } } } - if (object instanceof ScheduledModel) { - ScheduledModel after = ((ScheduledModel) object); + if (object instanceof Schedulable) { + Schedulable after = ((Schedulable) object); if (after.getCalendarId() > 0) { - ScheduledModel before = null; + Schedulable before = null; if (!addition) { before = storage.getObject(after.getClass(), new Request( - new Columns.Include("calendarId"), new Condition.Equals("id", after.getId()))); + new Columns.Include("calendarId"), new Condition.Equals("id", object.getId()))); } if (before == null || before.getCalendarId() != after.getCalendarId()) { checkPermission(Calendar.class, userId, after.getCalendarId()); @@ -156,7 +156,7 @@ public class PermissionsService { Notification before = null; if (!addition) { before = storage.getObject(after.getClass(), new Request( - new Columns.Include("commandId"), new Condition.Equals("id", after.getId()))); + new Columns.Include("commandId"), new Condition.Equals("id", object.getId()))); } if (before == null || before.getCommandId() != after.getCommandId()) { checkPermission(Command.class, userId, after.getCommandId()); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 2623c3486..028e4cd09 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -25,6 +25,7 @@ import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.AttributeUtil; +import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; @@ -259,9 +260,16 @@ public class FilterHandler extends ChannelInboundHandlerAdapter { } } + Device device = cacheManager.getObject(Device.class, deviceId); + if (device.getCalendarId() > 0) { + Calendar calendar = cacheManager.getObject(Calendar.class, device.getCalendarId()); + if (!calendar.checkMoment(position.getFixTime())) { + filterType.append("Calendar "); + } + } + if (filterType.length() > 0) { - String uniqueId = cacheManager.getObject(Device.class, deviceId).getUniqueId(); - LOGGER.info("Position filtered by {}filters from device: {}", filterType, uniqueId); + LOGGER.info("Position filtered by {}filters from device: {}", filterType, device.getUniqueId()); return true; } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index b7cffac49..2c582328e 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -22,7 +22,19 @@ import org.traccar.storage.StorageName; import java.util.Date; @StorageName("tc_devices") -public class Device extends GroupedModel implements Disableable { +public class Device extends GroupedModel implements Disableable, Schedulable { + + private long calendarId; + + @Override + public long getCalendarId() { + return calendarId; + } + + @Override + public void setCalendarId(long calendarId) { + this.calendarId = calendarId; + } private String name; diff --git a/src/main/java/org/traccar/model/Geofence.java b/src/main/java/org/traccar/model/Geofence.java index 9259028fb..ca6293651 100644 --- a/src/main/java/org/traccar/model/Geofence.java +++ b/src/main/java/org/traccar/model/Geofence.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 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. @@ -26,7 +26,19 @@ import org.traccar.storage.StorageName; import java.text.ParseException; @StorageName("tc_geofences") -public class Geofence extends ScheduledModel { +public class Geofence extends ExtendedModel implements Schedulable { + + private long calendarId; + + @Override + public long getCalendarId() { + return calendarId; + } + + @Override + public void setCalendarId(long calendarId) { + this.calendarId = calendarId; + } private String name; diff --git a/src/main/java/org/traccar/model/Notification.java b/src/main/java/org/traccar/model/Notification.java index b6a6e4cf5..6dcd9c9de 100644 --- a/src/main/java/org/traccar/model/Notification.java +++ b/src/main/java/org/traccar/model/Notification.java @@ -24,7 +24,19 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.storage.StorageName; @StorageName("tc_notifications") -public class Notification extends ScheduledModel { +public class Notification extends ExtendedModel implements Schedulable { + + private long calendarId; + + @Override + public long getCalendarId() { + return calendarId; + } + + @Override + public void setCalendarId(long calendarId) { + this.calendarId = calendarId; + } private boolean always; diff --git a/src/main/java/org/traccar/model/Report.java b/src/main/java/org/traccar/model/Report.java index 1556ecc9e..2ee7ae288 100644 --- a/src/main/java/org/traccar/model/Report.java +++ b/src/main/java/org/traccar/model/Report.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -18,7 +18,19 @@ package org.traccar.model; import org.traccar.storage.StorageName; @StorageName("tc_reports") -public class Report extends ScheduledModel { +public class Report extends ExtendedModel implements Schedulable { + + private long calendarId; + + @Override + public long getCalendarId() { + return calendarId; + } + + @Override + public void setCalendarId(long calendarId) { + this.calendarId = calendarId; + } private String type; diff --git a/src/main/java/org/traccar/model/Schedulable.java b/src/main/java/org/traccar/model/Schedulable.java new file mode 100644 index 000000000..331e77583 --- /dev/null +++ b/src/main/java/org/traccar/model/Schedulable.java @@ -0,0 +1,22 @@ +/* + * 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"); + * 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.model; + +public interface Schedulable { + long getCalendarId(); + void setCalendarId(long calendarId); +} diff --git a/src/main/java/org/traccar/model/ScheduledModel.java b/src/main/java/org/traccar/model/ScheduledModel.java deleted file mode 100644 index 9e6a4b9a6..000000000 --- a/src/main/java/org/traccar/model/ScheduledModel.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2018 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.model; - -public class ScheduledModel extends ExtendedModel { - - private long calendarId; - - public long getCalendarId() { - return calendarId; - } - - public void setCalendarId(long calendarId) { - this.calendarId = calendarId; - } -} diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 9d2350012..24abd7347 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 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. @@ -31,7 +31,7 @@ import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; -import org.traccar.model.ScheduledModel; +import org.traccar.model.Schedulable; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; @@ -244,8 +244,8 @@ public class CacheManager implements BroadcastInterface { if (((GroupedModel) before).getGroupId() != ((GroupedModel) object).getGroupId()) { invalidate = true; } - } else if (object instanceof ScheduledModel) { - if (((ScheduledModel) before).getCalendarId() != ((ScheduledModel) object).getCalendarId()) { + } else if (object instanceof Schedulable) { + if (((Schedulable) before).getCalendarId() != ((Schedulable) object).getCalendarId()) { invalidate = true; } } @@ -308,6 +308,12 @@ public class CacheManager implements BroadcastInterface { new Columns.All(), new Condition.Equals("id", deviceId))); if (device != null) { addObject(deviceId, device); + if (device.getCalendarId() > 0) { + var calendar = storage.getObject(Calendar.class, new Request( + new Columns.All(), new Condition.Equals("id", device.getCalendarId()))); + links.computeIfAbsent(Calendar.class, k -> new LinkedHashSet<>()).add(calendar.getId()); + addObject(deviceId, calendar); + } int groupDepth = 0; long groupId = device.getGroupId(); @@ -326,13 +332,12 @@ public class CacheManager implements BroadcastInterface { links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toSet())); for (var object : objects) { addObject(deviceId, object); - if (object instanceof ScheduledModel) { - var scheduled = (ScheduledModel) object; + if (object instanceof Schedulable) { + var scheduled = (Schedulable) object; if (scheduled.getCalendarId() > 0) { var calendar = storage.getObject(Calendar.class, new Request( new Columns.All(), new Condition.Equals("id", scheduled.getCalendarId()))); - links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) - .add(calendar.getId()); + links.computeIfAbsent(Calendar.class, k -> new LinkedHashSet<>()).add(calendar.getId()); addObject(deviceId, calendar); } } @@ -350,14 +355,12 @@ public class CacheManager implements BroadcastInterface { .filter(Notification::getAlways) .collect(Collectors.toList()); for (var notification : notifications) { - links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) - .add(notification.getId()); + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()).add(notification.getId()); addObject(deviceId, notification); if (notification.getCalendarId() > 0) { var calendar = storage.getObject(Calendar.class, new Request( new Columns.All(), new Condition.Equals("id", notification.getCalendarId()))); - links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) - .add(calendar.getId()); + links.computeIfAbsent(Calendar.class, k -> new LinkedHashSet<>()).add(calendar.getId()); addObject(deviceId, calendar); } } -- cgit v1.2.3 From d4c204914f907f7bbdf34a965500797b03fafdf8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 1 Jul 2023 21:52:41 -0700 Subject: Decode R31 heartbeat data --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 7 +++++++ src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 7013533bc..38c2219f8 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -828,6 +828,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } + if (type == MSG_STATUS && variant == Variant.VXT01) { + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + } + if (type == MSG_GPS_LBS_1) { if (variant == Variant.GT06E_CARD) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); @@ -1408,6 +1413,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_1 && length == 0x24) { variant = Variant.VXT01; + } else if (header == 0x7878 && type == MSG_STATUS && length == 0x0a) { + variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x31) { variant = Variant.WANWAY_S20; } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x2e) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 8f2c97f86..937c7eca1 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78780a130604ea04000006bc8a0d0a"), + Position.KEY_POWER, 0.0); + verifyAttributes(decoder, binary( "797900849404414c4d313d43353b414c4d323d43433b414c4d333d35433b535441313d43303b4459443d30313b534f533d303133323838333730302c2c3b43454e5445523d303133323838333730303b46454e43453d46656e63652c4f46462c302c302e3030303030302c302e3030303030302c3330302c494e206f72204f55542c313b00b79d120d0a")); -- cgit v1.2.3 From 957a68d4a378c0f9d5000bc00599427fd78e663d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Jul 2023 09:12:06 -0700 Subject: Reorganize GL200 text decoder --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 738 ++++++++++----------- 1 file changed, 369 insertions(+), 369 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index a0e217165..e33093d6f 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -70,372 +70,6 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); - private static final Pattern PATTERN_INF = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTINF,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17},)?") // vin - .expression("(?:[^,]+)?,") // device name - .number("(xx),") // state - .expression("(?:[0-9Ff]{20})?,") // iccid - .number("(d{1,2}),") // rssi - .number("d{1,2},") - .expression("[01]{1,2},") // external power - .number("([d.]+)?,") // odometer or external power - .number("d*,") // backup battery or lightness - .number("(d+.d+),") // battery - .expression("([01]),") // charging - .number("(?:d),") // led - .number("(?:d)?,") // gps on need - .number("(?:d)?,") // gps antenna type - .number("(?:d)?,").optional() // gps antenna state - .number("d{14},") // last fix time - .groupBegin() - .number("(d+),") // battery percentage - .number("[d.]*,") // flash type / power - .number("(-?[d.]+)?,,,") // temperature - .or() - .expression("(?:[01])?,").optional() // pin15 mode - .number("(d+)?,") // adc1 - .number("(d+)?,").optional() // adc2 - .number("(xx)?,") // digital input - .number("(xx)?,") // digital output - .number("[-+]dddd,") // timezone - .expression("[01],") // daylight saving - .or() - .any() - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_VER = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTVER,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .expression("([^,]*),") // device type - .number("(xxxx),") // firmware version - .number("(xxxx),") // hardware version - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(d{1,2}.?d?)?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3}.?d?)?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+)?,") // mcc - .number("(d+)?,") // mnc - .groupBegin() - .number("(d+),") // lac - .number("(d+),") // cid - .or() - .number("(x+)?,") // lac - .number("(x+)?,") // cid - .groupEnd() - .number("(?:d+|(d+.d))?,") // rssi / odometer - .compile(); - - private static final Pattern PATTERN_OBD = new PatternBuilder() - .text("+RESP:GTOBD,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17})?,") // vin - .expression("[^,]{0,20},") // device name - .expression("[01],") // report type - .number("x{1,8},") // report mask - .expression("(?:[0-9A-Z]{17})?,") // vin - .number("[01],") // obd connect - .number("(?:d{1,5})?,") // obd voltage - .number("(?:x{8})?,") // support pids - .number("(d{1,5})?,") // engine rpm - .number("(d{1,3})?,") // speed - .number("(-?d{1,3})?,") // coolant temp - .number("(d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d{1,5})?,") // dtcs cleared distance - .number("(?:d{1,5})?,") - .expression("([01])?,") // obd connect - .number("(d{1,3})?,") // number of dtcs - .number("(x*),") // dtcs - .number("(d{1,3})?,") // throttle - .number("(?:d{1,3})?,") // engine load - .number("(d{1,3})?,") // fuel level - .expression("(?:[0-9A],)?") // obd protocol - .number("(d+),") // odometer - .expression(PATTERN_LOCATION.pattern()) - .number("(d{1,7}.d)?,") // odometer - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_FRI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:([0-9A-Z]{17}),)?") // vin - .expression("[^,]*,") // device name - .number("(d+)?,") // power - .number("(d{1,2}),").optional() // report type - .number("d{1,2},").optional() // count - .number("d*,").optional() // reserved - .number("(d+),").optional() // battery - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .groupBegin() - .number("d{1,2},,") - .number("(d{1,3}),") // battery - .number("[01],") // mode - .number("(?:[01])?,") // motion - .number("(?:-?d{1,2}.d)?,") // temperature - .or() - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,") // adc 2 - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .number("(d+)?,") // rpm - .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d+)?,") // fuel level - .or() - .number("(-?d),") // rssi - .number("(d{1,3}),") // battery - .or() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .groupEnd() - .any() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_ERI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTERI,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(x{8}),") // mask - .number("(d+)?,") // power - .number("d{1,2},") // report type - .number("d{1,2},") // count - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .groupBegin() - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,").optional() // adc 2 - .groupBegin() - .number("(x+)?,") // adc 3 - .number("(xx),") // inputs - .number("(xx),") // outputs - .or() - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .groupEnd() - .expression("(.*)") // additional data - .or() - .number("d*,,") - .number("(d+),") // battery - .any() - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_IGN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTIG[NF],") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d+,") // ignition off duration - .expression(PATTERN_LOCATION.pattern()) - .number("(d{5}:dd:dd)?,") // hour meter - .number("(d{1,7}.d)?,") // odometer - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_LSW = new PatternBuilder() - .text("+RESP:").expression("GT[LT]SW,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("[01],") // type - .number("([01]),") // state - .expression(PATTERN_LOCATION.pattern()) - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_IDA = new PatternBuilder() - .text("+RESP:GTIDA,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,,") // device name - .number("([^,]+),") // rfid - .expression("[01],") // report type - .number("1,") // count - .expression(PATTERN_LOCATION.pattern()) - .number("(d+.d),") // odometer - .text(",,,,") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_WIF = new PatternBuilder() - .text("+RESP:GTWIF,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(d+),") // count - .number("((?:x{12},-?d+,,,,)+),,,,") // wifi - .number("(d{1,3}),") // battery - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_GSM = new PatternBuilder() - .text("+RESP:GTGSM,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:STR|CTN|NMR|RTL),") // fix type - .expression("(.*)") // cells - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_PNA = new PatternBuilder() - .text("+RESP:GT").expression("P[NF]A,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_DAR = new PatternBuilder() - .text("+RESP:GTDAR,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(d),") // warning type - .number("(d{1,2}),,,") // fatigue degree - .expression(PATTERN_LOCATION.pattern()) - .any() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_DTT = new PatternBuilder() - .text("+RESP:GTDTT,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,,,") // device name - .number("d,") // data type - .number("d+,") // data length - .number("(x+),") // data - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d*,") - .number("(x{1,2}),") // report type - .number("d{1,2},") // count - .number("d*,").optional() // reserved - .expression(PATTERN_LOCATION.pattern()) - .groupBegin() - .number("(?:(d{1,7}.d)|0)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() - .number("(d{1,7}.d)?,") // odometer - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_BASIC = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF)").text(":") - .expression("GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version - .number("(d{15}|x{14}),") // imei - .any() - .text(",") - .number("(d{1,2})?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(x+),") // lac - .number("(x+),").optional(4) // cell - .any() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - private Object decodeAck(Channel channel, SocketAddress remoteAddress, String sentence, String type) { Parser parser = new Parser(PATTERN_ACK, sentence); if (parser.matches()) { @@ -487,13 +121,54 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { private Long parseHours(String hoursString) { if (hoursString != null) { String[] hours = hoursString.split(":"); - return (long) (Integer.parseInt(hours[0]) * 3600 - + (hours.length > 1 ? Integer.parseInt(hours[1]) * 60 : 0) + return (Integer.parseInt(hours[0]) * 3600L + + (hours.length > 1 ? Integer.parseInt(hours[1]) * 60L : 0) + (hours.length > 2 ? Integer.parseInt(hours[2]) : 0)) * 1000; } return null; } + private static final Pattern PATTERN_INF = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTINF,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:[0-9A-Z]{17},)?") // vin + .expression("(?:[^,]+)?,") // device name + .number("(xx),") // state + .expression("(?:[0-9Ff]{20})?,") // iccid + .number("(d{1,2}),") // rssi + .number("d{1,2},") + .expression("[01]{1,2},") // external power + .number("([d.]+)?,") // odometer or external power + .number("d*,") // backup battery or lightness + .number("(d+.d+),") // battery + .expression("([01]),") // charging + .number("(?:d),") // led + .number("(?:d)?,") // gps on need + .number("(?:d)?,") // gps antenna type + .number("(?:d)?,").optional() // gps antenna state + .number("d{14},") // last fix time + .groupBegin() + .number("(d+),") // battery percentage + .number("[d.]*,") // flash type / power + .number("(-?[d.]+)?,,,") // temperature + .or() + .expression("(?:[01])?,").optional() // pin15 mode + .number("(d+)?,") // adc1 + .number("(d+)?,").optional() // adc2 + .number("(xx)?,") // digital input + .number("(xx)?,") // digital output + .number("[-+]dddd,") // timezone + .expression("[01],") // daylight saving + .or() + .any() + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_INF, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -554,6 +229,20 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_VER = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTVER,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .expression("([^,]*),") // device type + .number("(xxxx),") // firmware version + .number("(xxxx),") // hardware version + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + private Object decodeVer(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_VER, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -574,6 +263,28 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { parser.skip(19); } + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .number("(d{1,2}.?d?)?,") // hdop + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3}.?d?)?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(d+)?,") // mcc + .number("(d+)?,") // mnc + .groupBegin() + .number("(d+),") // lac + .number("(d+),") // cid + .or() + .number("(x+)?,") // lac + .number("(x+)?,") // cid + .groupEnd() + .number("(?:d+|(d+.d))?,") // rssi / odometer + .compile(); + private void decodeLocation(Position position, Parser parser) { Double hdop = parser.nextDouble(); position.setValid(hdop == null || hdop > 0); @@ -608,6 +319,41 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } } + private static final Pattern PATTERN_OBD = new PatternBuilder() + .text("+RESP:GTOBD,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:[0-9A-Z]{17})?,") // vin + .expression("[^,]{0,20},") // device name + .expression("[01],") // report type + .number("x{1,8},") // report mask + .expression("(?:[0-9A-Z]{17})?,") // vin + .number("[01],") // obd connect + .number("(?:d{1,5})?,") // obd voltage + .number("(?:x{8})?,") // support pids + .number("(d{1,5})?,") // engine rpm + .number("(d{1,3})?,") // speed + .number("(-?d{1,3})?,") // coolant temp + .number("(d+.?d*|Inf|NaN)?,") // fuel consumption + .number("(d{1,5})?,") // dtcs cleared distance + .number("(?:d{1,5})?,") + .expression("([01])?,") // obd connect + .number("(d{1,3})?,") // number of dtcs + .number("(x*),") // dtcs + .number("(d{1,3})?,") // throttle + .number("(?:d{1,3})?,") // engine load + .number("(d{1,3})?,") // fuel level + .expression("(?:[0-9A],)?") // obd protocol + .number("(d+),") // odometer + .expression(PATTERN_LOCATION.pattern()) + .number("(d{1,7}.d)?,") // odometer + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_OBD, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -858,6 +604,51 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } } + private static final Pattern PATTERN_FRI = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:([0-9A-Z]{17}),)?") // vin + .expression("[^,]*,") // device name + .number("(d+)?,") // power + .number("(d{1,2}),").optional() // report type + .number("d{1,2},").optional() // count + .number("d*,").optional() // reserved + .number("(d+),").optional() // battery + .expression("((?:") + .expression(PATTERN_LOCATION.pattern()) + .expression(")+)") + .groupBegin() + .number("d{1,2},,") + .number("(d{1,3}),") // battery + .number("[01],") // mode + .number("(?:[01])?,") // motion + .number("(?:-?d{1,2}.d)?,") // temperature + .or() + .number("(d{1,7}.d)?,") // odometer + .number("(d{5}:dd:dd)?,") // hour meter + .number("(x+)?,") // adc 1 + .number("(x+)?,") // adc 2 + .number("(d{1,3})?,") // battery + .number("(?:(xx)(xx)(xx))?,") // device status + .number("(d+)?,") // rpm + .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption + .number("(d+)?,") // fuel level + .or() + .number("(-?d),") // rssi + .number("(d{1,3}),") // battery + .or() + .number("(d{1,7}.d)?,").optional() // odometer + .number("(d{1,3})?,") // battery + .groupEnd() + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_FRI, sentence); if (!parser.matches()) { @@ -938,6 +729,44 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return positions; } + private static final Pattern PATTERN_ERI = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTERI,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(x{8}),") // mask + .number("(d+)?,") // power + .number("d{1,2},") // report type + .number("d{1,2},") // count + .expression("((?:") + .expression(PATTERN_LOCATION.pattern()) + .expression(")+)") + .groupBegin() + .number("(d{1,7}.d)?,") // odometer + .number("(d{5}:dd:dd)?,") // hour meter + .number("(x+)?,") // adc 1 + .number("(x+)?,").optional() // adc 2 + .groupBegin() + .number("(x+)?,") // adc 3 + .number("(xx),") // inputs + .number("(xx),") // outputs + .or() + .number("(d{1,3})?,") // battery + .number("(?:(xx)(xx)(xx))?,") // device status + .groupEnd() + .expression("(.*)") // additional data + .or() + .number("d*,,") + .number("(d+),") // battery + .any() + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeEri(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_ERI, sentence); if (!parser.matches()) { @@ -1041,6 +870,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return positions; } + private static final Pattern PATTERN_IGN = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTIG[NF],") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("d+,") // ignition off duration + .expression(PATTERN_LOCATION.pattern()) + .number("(d{5}:dd:dd)?,") // hour meter + .number("(d{1,7}.d)?,") // odometer + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_IGN, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1059,6 +904,21 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_LSW = new PatternBuilder() + .text("+RESP:").expression("GT[LT]SW,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("[01],") // type + .number("([01]),") // state + .expression(PATTERN_LOCATION.pattern()) + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeLsw(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_LSW, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1075,6 +935,24 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_IDA = new PatternBuilder() + .text("+RESP:GTIDA,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,,") // device name + .number("([^,]+),") // rfid + .expression("[01],") // report type + .number("1,") // count + .expression(PATTERN_LOCATION.pattern()) + .number("(d+.d),") // odometer + .text(",,,,") + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeIda(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_IDA, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1093,6 +971,21 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_WIF = new PatternBuilder() + .text("+RESP:GTWIF,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(d+),") // count + .number("((?:x{12},-?d+,,,,)+),,,,") // wifi + .number("(d{1,3}),") // battery + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeWif(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_WIF, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1119,6 +1012,19 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_GSM = new PatternBuilder() + .text("+RESP:GTGSM,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:STR|CTN|NMR|RTL),") // fix type + .expression("(.*)") // cells + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeGsm(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_GSM, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1145,6 +1051,18 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_PNA = new PatternBuilder() + .text("+RESP:GT").expression("P[NF]A,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodePna(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_PNA, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1159,6 +1077,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_DAR = new PatternBuilder() + .text("+RESP:GTDAR,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(d),") // warning type + .number("(d{1,2}),,,") // fatigue degree + .expression(PATTERN_LOCATION.pattern()) + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeDar(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_DAR, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1182,6 +1116,21 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_DTT = new PatternBuilder() + .text("+RESP:GTDTT,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,,,") // device name + .number("d,") // data type + .number("d+,") // data length + .number("(x+),") // data + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeDtt(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_DTT, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1205,6 +1154,29 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("d*,") + .number("(x{1,2}),") // report type + .number("d{1,2},") // count + .number("d*,").optional() // reserved + .expression(PATTERN_LOCATION.pattern()) + .groupBegin() + .number("(?:(d{1,7}.d)|0)?,").optional() // odometer + .number("(d{1,3})?,") // battery + .or() + .number("(d{1,7}.d)?,") // odometer + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)") // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { Parser parser = new Parser(PATTERN, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1255,6 +1227,34 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_BASIC = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF)").text(":") + .expression("GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version + .number("(d{15}|x{14}),") // imei + .any() + .text(",") + .number("(d{1,2})?,") // hdop + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+),").optional(4) // cell + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence, String type) { Parser parser = new Parser(PATTERN_BASIC, sentence); Position position = initPosition(parser, channel, remoteAddress); -- cgit v1.2.3 From a8a06ffd494fc7161ca0edca39ae35be865a383f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Jul 2023 09:41:32 -0700 Subject: Support GV350M accessories --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 104 +++++++++++++++++++++ .../protocol/Gl200TextProtocolDecoderTest.java | 8 ++ 2 files changed, 112 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index e33093d6f..bfd0a4cbb 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -1154,6 +1154,104 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_BAA = new PatternBuilder() + .text("+RESP:GTBAA,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("x+,") // index + .number("d,") // accessory type + .number("d,") // accessory model + .number("x+,") // alarm type + .number("(x{4}),") // append mask + .expression("((?:[^,]+,){0,6})") // accessory optionals + .expression(PATTERN_LOCATION.pattern()) + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private Object decodeBaa(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_BAA, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int mask = parser.nextHexInt(); + String[] values = parser.next().split(","); + int index = 0; + if (BitUtil.check(mask, 0)) { + position.set("accessoryName", values[index++]); + } + if (BitUtil.check(mask, 1)) { + position.set("accessoryMac", values[index++]); + } + if (BitUtil.check(mask, 2)) { + position.set("accessoryStatus", Integer.parseInt(values[index++])); + } + if (BitUtil.check(mask, 3)) { + position.set("accessoryVoltage", Integer.parseInt(values[index++]) * 0.001); + } + if (BitUtil.check(mask, 4)) { + position.set("accessoryTemp", Integer.parseInt(values[index++])); + } + if (BitUtil.check(mask, 5)) { + position.set("accessoryHumidity", Integer.parseInt(values[index])); + } + + decodeLocation(position, parser); + + decodeDeviceTime(position, parser); + + return position; + } + + private static final Pattern PATTERN_BID = new PatternBuilder() + .text("+RESP:GTBID,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("d,") // count + .number("d,") // accessory model + .number("(x{4}),") // append mask + .expression("((?:[^,]+,){0,2})") // accessory optionals + .expression(PATTERN_LOCATION.pattern()) + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private Object decodeBid(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_BID, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int mask = parser.nextHexInt(); + String[] values = parser.next().split(","); + int index = 0; + if (BitUtil.check(mask, 1)) { + position.set("accessoryMac", values[index++]); + } + if (BitUtil.check(mask, 3)) { + position.set("accessoryVoltage", Integer.parseInt(values[index]) * 0.001); + } + + decodeLocation(position, parser); + + decodeDeviceTime(position, parser); + + return position; + } + private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF):GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -1402,6 +1500,12 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "DTT": result = decodeDtt(channel, remoteAddress, sentence); break; + case "BAA": + result = decodeBaa(channel, remoteAddress, sentence); + break; + case "BID": + result = decodeBid(channel, remoteAddress, sentence); + break; default: result = decodeOther(channel, remoteAddress, sentence, type); break; diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 760671cd9..fcd2c6be4 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,14 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "+RESP:GTBAA,F1040C,862599050497393,GV350M,FF,3,0,04,000A,780541256AE9,3065,0,0.0,213,2908.3,-78.691944,-0.951426,20230511173150,,,,,,20230511175001,0159$"), + "accessoryVoltage", 3.065); + + verifyAttribute(decoder, buffer( + "+RESP:GTBID,C20105,866833040163013,GV350M,1,0,000A,B80EA11FF800,2934,0,0.0,0,1506.5,-99.192686,18.932709,20221026025339,0334,0020,0232,029D4E02,,20221026181026,9F1D$"), + "accessoryVoltage", 2.934); + verifyAttribute(decoder, buffer( "+RESP:GTDTT,410502,864802030541621,,,,1,35,45637561747261636b0d0a434f4d422c302c39342e302c2d312e302c2c2c4844430d0a,20230421034626,EA2E$"), Position.KEY_FUEL_LEVEL, 94.0); -- 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 'src/main/java/org') 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 From 5e18cb586d34aa3db0417cef9635bf1d9cae6e18 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 3 Jul 2023 21:21:38 -0700 Subject: Support GV350M CAN messages --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 25 ++++++++++++++++------ .../protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index bfd0a4cbb..911af8d73 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -400,7 +400,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); position.setDeviceId(deviceSession.getDeviceId()); - index += 1; // device name + String deviceName = values[index++]; index += 1; // report type index += 1; // canbus state long reportMask = Long.parseLong(values[index++], 16); @@ -442,11 +442,11 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(reportMask, 11) && !values[index++].isEmpty()) { position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Double.parseDouble(values[index - 1]))); } - if (BitUtil.check(reportMask, 12)) { - position.set(Position.KEY_DRIVING_TIME, Double.parseDouble(values[index++])); + if (BitUtil.check(reportMask, 12) && !values[index++].isEmpty()) { + position.set(Position.KEY_DRIVING_TIME, Double.parseDouble(values[index - 1])); } - if (BitUtil.check(reportMask, 13)) { - position.set("idleHours", Double.parseDouble(values[index++])); + if (BitUtil.check(reportMask, 13) && !values[index++].isEmpty()) { + position.set("idleHours", Double.parseDouble(values[index - 1])); } if (BitUtil.check(reportMask, 14) && !values[index++].isEmpty()) { position.set("idleFuelConsumption", Double.parseDouble(values[index - 1])); @@ -472,8 +472,19 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(reportMask, 21) && !values[index++].isEmpty()) { position.set("engineOverspeed", Double.parseDouble(values[index - 1])); } - if (BitUtil.check(reportMask, 29)) { - reportMaskExt = Long.parseLong(values[index++], 16); + if ("GV350M".equals(deviceName)) { + if (BitUtil.check(reportMask, 22)) { + index += 1; // impulse distance + } + if (BitUtil.check(reportMask, 23)) { + index += 1; // gross vehicle weight + } + if (BitUtil.check(reportMask, 24)) { + index += 1; // catalyst liquid level + } + } + if (BitUtil.check(reportMask, 29) && !values[index++].isEmpty()) { + reportMaskExt = Long.parseLong(values[index - 1], 16); } if (BitUtil.check(reportMaskExt, 0) && !values[index++].isEmpty()) { position.set("adBlueLevel", Integer.parseInt(values[index - 1])); diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index fcd2c6be4..f0dd10772 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttributes(decoder, buffer( + "+RESP:GTCAN,F1040C,862599050497393,GV350M,0,0,FFFFFFFF,,1,,,,,,,,,,,,,,,,,,,,,,,0,,,1,0.0,70,2961.6,-78.691750,-0.951135,20230703191659,,,,,,20230703191659,5A4A$")); + verifyAttribute(decoder, buffer( "+RESP:GTBAA,F1040C,862599050497393,GV350M,FF,3,0,04,000A,780541256AE9,3065,0,0.0,213,2908.3,-78.691944,-0.951426,20230511173150,,,,,,20230511175001,0159$"), "accessoryVoltage", 3.065); -- cgit v1.2.3 From 8b4d3ee0b96407ad3c889bc3bb0261e5ebe60532 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Jul 2023 07:25:53 -0700 Subject: Minifinder decode phone numbers --- .../org/traccar/protocol/MiniFinderProtocolDecoder.java | 16 +++++++++++++++- .../traccar/protocol/MiniFinderProtocolDecoderTest.java | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java index f2e5eb905..1fdb1ece0 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -143,7 +143,7 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { } DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null || !sentence.matches("![35A-D],.*")) { + if (deviceSession == null || !sentence.matches("![345A-D],.*")) { return null; } @@ -161,6 +161,20 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type.equals("4")) { + + String[] values = sentence.split(","); + + getLastLocation(position, null); + + for (int i = 1; i <= 3; i++) { + if (!values[i + 1].isEmpty()) { + position.set("phone" + i, values[i + 1]); + } + } + + return position; + } else if (type.equals("5")) { String[] values = sentence.split(","); diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java index d955d8e50..712d59dc9 100644 --- a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java @@ -20,6 +20,10 @@ public class MiniFinderProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "!1,123456789012345")); + verifyAttribute(decoder, text( + "!4,10,040123,,,1.0,110,0,0S,33"), + "phone1", "040123"); + verifyAttribute(decoder, text( "!5,17,V,50"), Position.KEY_BATTERY_LEVEL, 50); -- cgit v1.2.3 From 52799453e0ee9a9db3cbad58138712c8c40c458f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Jul 2023 08:02:33 -0700 Subject: iStartek VT200 ACC on time --- .../org/traccar/protocol/StartekProtocolDecoder.java | 16 ++++++++++------ .../org/traccar/protocol/StartekProtocolDecoderTest.java | 4 ++++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index d08bb92a8..9c749c8d9 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -72,12 +72,10 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("(x+)") // battery .expression("([^,]+)?") // adc .groupBegin() - .text(",") - .number("d,") // extended - .expression("([^,]+)?") // fuel + .number(",d+") // extended + .expression(",([^,]+)?") // fuel .groupBegin() - .text(",") - .expression("([^,]+)?") // temperature + .expression(",([^,]+)?") // temperature .groupBegin() .text(",") .groupBegin() @@ -91,9 +89,11 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("(d+)?|") // instant fuel .number("(d+)[%L]").optional() // fuel level .groupEnd("?") + .number(",(d+)").optional() // hours .groupEnd("?") .groupEnd("?") .groupEnd("?") + .any() .compile(); private String decodeAlarm(int value) { @@ -224,7 +224,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } } - if (parser.hasNextAny(6)) { + if (parser.hasNextAny(9)) { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); position.set("airFlow", parser.nextInt()); @@ -242,6 +242,10 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); } + if (parser.hasNext()) { + position.set(Position.KEY_HOURS, parser.nextInt() * 1000L); + } + return position; } diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index 361e6e6f2..9b1362f5d 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = inject(new StartekProtocolDecoder(null)); + verifyAttribute(decoder, text( + "&&s148,868703050178631,000,37,,230704040211,A,22.678565,114.046011,31,0.5,0,339,77,8,460|0|249F|0AC2620D,27,0000001D,02,00,04F2|01A1|0000|0000,129,,,,949037"), + Position.KEY_HOURS, 9490000L); + verifyAttribute(decoder, text( "&&x164,869926040743375,000,0,,220705205955,A,33.326001,44.445318,10,1.2,0,57,8,925,418|40|038C|000083CD,31,00000015,00,00,0016|016A|0000|0000,1,,,686|33||44|99|14|124|11|8D"), Position.KEY_FUEL_CONSUMPTION, 1.1); -- cgit v1.2.3 From 7d4f1fb9a037df92f9fbaa020806ed989d86b1e2 Mon Sep 17 00:00:00 2001 From: geduxas Date: Wed, 5 Jul 2023 23:32:21 +0300 Subject: Update TeltonikaProtocolDecoder.java Small fix for #5129 thought traccar expects value in kilometer. --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index c6531c790..c8e0005f9 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -252,7 +252,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(83, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_USED, b.readUnsignedInt() * 0.1)); register(84, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_LEVEL, b.readUnsignedShort() * 0.1)); register(85, fmbXXX, (p, b) -> p.set(Position.KEY_RPM, b.readUnsignedShort())); - register(87, fmbXXX, (p, b) -> p.set(Position.KEY_OBD_ODOMETER, b.readUnsignedInt() * 0.001)); + register(87, fmbXXX, (p, b) -> p.set(Position.KEY_OBD_ODOMETER, b.readUnsignedInt())); register(89, fmbXXX, (p, b) -> p.set("fuelLevelPercentage", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); register(110, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_CONSUMPTION, b.readUnsignedShort() * 0.1)); -- cgit v1.2.3 From c12f74fea206191877d4a727547bfdb0c9b938cc Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Fri, 7 Jul 2023 08:08:48 -0400 Subject: Keep same structure as before --- .../traccar/protocol/LaipacProtocolDecoder.java | 39 +++++++++++----------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 3b654db0c..dbac159b3 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -110,26 +110,25 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { private String decodeEvent(String event, Position position) { - if (event.length() != 1) { - return event; - } - - int inputStatusInt = 0; - char inputStatus = event.charAt(0); - - if (inputStatus >= 'A' && inputStatus <= 'D') { - inputStatusInt = inputStatus - 'A'; - } else if (inputStatus >= 'O' && inputStatus <= 'R') { - inputStatusInt = inputStatus - 'O' + 4; - } else { - return event; - } - - position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); - position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); - position.set(Position.PREFIX_IN + 3, inputStatusInt & 4); - - return null; + if (event.length() == 1) { + char inputStatus = event.charAt(0); + if (inputStatus >= 'A' && inputStatus <= 'D') { + int inputStatusInt = inputStatus - 'A'; + position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); + position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + position.set(Position.PREFIX_IN + 3, 0); + return null; + } else if (inputStatus >= 'O' && inputStatus <= 'R') { + int inputStatusInt = inputStatus - 'O'; + position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); + position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + position.set(Position.PREFIX_IN + 3, 1); + return null; + } + } + + return event; + } private void sendEventResponse( -- cgit v1.2.3 From 83cb4c11d740a3645a5b9a5dafbc13b245c89a07 Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Fri, 7 Jul 2023 08:16:03 -0400 Subject: Change tabs to spaces --- .../org/traccar/protocol/LaipacProtocolDecoder.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index dbac159b3..2237dcebc 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -111,23 +111,23 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { private String decodeEvent(String event, Position position) { if (event.length() == 1) { - char inputStatus = event.charAt(0); - if (inputStatus >= 'A' && inputStatus <= 'D') { - int inputStatusInt = inputStatus - 'A'; - position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); - position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + char inputStatus = event.charAt(0); + if (inputStatus >= 'A' && inputStatus <= 'D') { + int inputStatusInt = inputStatus - 'A'; + position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); + position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); position.set(Position.PREFIX_IN + 3, 0); - return null; - } else if (inputStatus >= 'O' && inputStatus <= 'R') { + return null; + } else if (inputStatus >= 'O' && inputStatus <= 'R') { int inputStatusInt = inputStatus - 'O'; position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); - position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); position.set(Position.PREFIX_IN + 3, 1); return null; } - } + } - return event; + return event; } -- cgit v1.2.3 From eb7c310a6337328f73c33cb8f0e222dc286925f1 Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Fri, 7 Jul 2023 08:21:01 -0400 Subject: Remove trailing spaces --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 2237dcebc..60a9365c5 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -126,9 +126,9 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { return null; } } - + return event; - + } private void sendEventResponse( -- cgit v1.2.3 From 19e00af6d0c7b666841b181438e401bb8e7415ff Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Fri, 7 Jul 2023 23:24:23 -0400 Subject: Use BitUtil instead of logical bitwise AND operator --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 60a9365c5..c2146c22d 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -28,6 +28,7 @@ import org.traccar.helper.PatternBuilder; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.helper.BitUtil; import java.net.SocketAddress; import java.util.regex.Pattern; @@ -114,14 +115,14 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { char inputStatus = event.charAt(0); if (inputStatus >= 'A' && inputStatus <= 'D') { int inputStatusInt = inputStatus - 'A'; - position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); - position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + position.set(Position.PREFIX_IN + 1, BitUtil.check(inputStatusInt, 0)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(inputStatusInt, 1)); position.set(Position.PREFIX_IN + 3, 0); return null; } else if (inputStatus >= 'O' && inputStatus <= 'R') { int inputStatusInt = inputStatus - 'O'; - position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); - position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + position.set(Position.PREFIX_IN + 1, BitUtil.check(inputStatusInt, 0)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(inputStatusInt, 1)); position.set(Position.PREFIX_IN + 3, 1); return null; } -- cgit v1.2.3 From 3ca63fb7a345a7b28f58b08874f02659d47d4a66 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 8 Jul 2023 07:25:22 -0700 Subject: Configurable T622 Iridium format --- .../protocol/T622IridiumProtocolDecoder.java | 111 ++++++++++++++++----- .../protocol/T622IridiumProtocolDecoderTest.java | 2 + 2 files changed, 88 insertions(+), 25 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java index 6a81a452a..1178b9b83 100644 --- a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java @@ -19,20 +19,44 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Position; import org.traccar.session.DeviceSession; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; public class T622IridiumProtocolDecoder extends BaseProtocolDecoder { + private String format; + public T622IridiumProtocolDecoder(Protocol protocol) { super(protocol); } + @Override + protected void init() { + super.init(); + } + + public List getParameters(long deviceId) { + String value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_FORMAT.withPrefix(getProtocolName()), deviceId); + return Arrays.stream((value != null ? value : format).split(",")) + .map(s -> Integer.parseInt(s, 16)) + .collect(Collectors.toList()); + } + + public void setFormat(String format) { + this.format = format; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -61,31 +85,68 @@ public class T622IridiumProtocolDecoder extends BaseProtocolDecoder { 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 + List parameters = getParameters(deviceSession.getDeviceId()); + + for (int parameter : parameters) { + switch (parameter) { + case 0x01: + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + break; + case 0x02: + position.setLatitude(buf.readIntLE() / 1000000.0); + break; + case 0x03: + position.setLongitude(buf.readIntLE() / 1000000.0); + break; + case 0x04: + position.setTime(new Date((buf.readUnsignedIntLE() + 946713600) * 1000)); + break; + case 0x05: + position.setValid(buf.readUnsignedByte() > 0); + break; + case 0x06: + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + break; + case 0x07: + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + break; + case 0x08: + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + break; + case 0x09: + position.setCourse(buf.readUnsignedShortLE()); + break; + case 0x0A: + position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + break; + case 0x0B: + position.setAltitude(buf.readShortLE()); + break; + case 0x0C: + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + break; + case 0x0D: + position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 1000); + break; + case 0x14: + position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + break; + case 0x15: + position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + break; + case 0x19: + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); + break; + case 0x1A: + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); + break; + case 0x1B: + buf.readUnsignedByte(); // geofence + break; + default: + break; + } + } return position; } diff --git a/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java index 4bc79fbe8..17b252618 100644 --- a/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java @@ -12,6 +12,8 @@ public class T622IridiumProtocolDecoderTest extends ProtocolTest { var decoder = inject(new T622IridiumProtocolDecoder(null)); + decoder.setFormat("01,02,03,04,05,08"); + verifyPosition(decoder, binary( "01003301001c2a8cef8333303034333430363735343836353000001700006461d512020011232f03a0fff1c85d0612b3f02b00000048")); -- cgit v1.2.3 From 7a59e7a1924bcab3184d1031273c51c9211a842a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 8 Jul 2023 07:28:37 -0700 Subject: Remove init --- src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java index 1178b9b83..27b7baf54 100644 --- a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java @@ -40,11 +40,6 @@ public class T622IridiumProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - @Override - protected void init() { - super.init(); - } - public List getParameters(long deviceId) { String value = AttributeUtil.lookup( getCacheManager(), Keys.PROTOCOL_FORMAT.withPrefix(getProtocolName()), deviceId); -- cgit v1.2.3 From 5b5f5d04863d3ca766c66441d8e1a8925e3e3d41 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 8 Jul 2023 07:36:01 -0700 Subject: Fix format config --- src/main/java/org/traccar/config/Keys.java | 2 +- src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e171511e6..6f5360c22 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -238,7 +238,7 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_FORMAT = new StringConfigSuffix( ".format", - List.of(KeyType.DEVICE)); + List.of(KeyType.CONFIG, KeyType.DEVICE)); /** * Protocol date format. Used by protocols that have configurable date format. diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index aa23bfac5..193005e28 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -61,10 +61,10 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { @Override protected void init() { setFormat(getConfig().getString( - getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#," + Keys.PROTOCOL_FORMAT.withPrefix(getProtocolName()), "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#," + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#")); - setDateFormat(getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); + setDateFormat(getConfig().getString(Keys.PROTOCOL_DATE_FORMAT.withPrefix(getProtocolName()), "yyMMddHHmmss")); } public String[] getFormat(long deviceId) { -- cgit v1.2.3 From 8790fed8864f9ce41fe219f8a757cc9dedec272d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 9 Jul 2023 06:32:18 -0700 Subject: Check enabled notification types --- src/main/java/org/traccar/notification/NotificatorManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index c3ee7b480..b6ee760f3 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -66,7 +66,7 @@ public class NotificatorManager { public Notificator getNotificator(String type) { var clazz = NOTIFICATORS_ALL.get(type); - if (clazz != null) { + if (clazz != null && types.contains(type)) { var notificator = injector.getInstance(clazz); if (notificator != null) { return notificator; -- cgit v1.2.3 From 92e90931cd806d4b2f53ff946a19b46595f856e9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 9 Jul 2023 06:37:34 -0700 Subject: Support new line in text commands --- src/main/java/org/traccar/BaseProtocol.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index d19fc307e..1948becc0 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.java @@ -105,7 +105,8 @@ public abstract class BaseProtocol implements Protocol { } else if (command.getType().equals(Command.TYPE_CUSTOM)) { String data = command.getString(Command.KEY_DATA); if (BasePipelineFactory.getHandler(channel.pipeline(), StringEncoder.class) != null) { - channel.writeAndFlush(new NetworkMessage(data, remoteAddress)); + channel.writeAndFlush(new NetworkMessage( + data.replace("\\r", "\r").replace("\\n", "\n"), remoteAddress)); } else { ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(data)); channel.writeAndFlush(new NetworkMessage(buf, remoteAddress)); -- cgit v1.2.3 From d2ce5af3478265c6c047f5ec4bf206baebb467d1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 9 Jul 2023 07:32:49 -0700 Subject: Handle R31 protocol variant --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 6 +++++- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 38c2219f8..5db06fc41 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -806,7 +806,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type) && buf.readableBytes() > 6) { - decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM && type != MSG_LBS_STATUS); + boolean hasLength = hasStatus(type) + && type != MSG_LBS_STATUS + && type != MSG_LBS_ALARM + && (type != MSG_GPS_LBS_STATUS_1 || variant != Variant.VXT01); + decodeLbs(position, buf, type, hasLength); } if (hasStatus(type)) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 937c7eca1..04f41a5ee 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78782416160501000221c0027c5e180c2b9c8d00150301cc002503002bde20050f01000004bd320d0a"), + Position.KEY_ALARM, Position.ALARM_SOS); + verifyAttribute(decoder, binary( "78780a130604ea04000006bc8a0d0a"), Position.KEY_POWER, 0.0); -- cgit v1.2.3 From 536888fd7e64f00ca9693ea9b41624360949c8ab Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Sun, 9 Jul 2023 14:01:12 -0400 Subject: Conditionally set digital input 3 and analog input 2 according to device model --- .../traccar/protocol/LaipacProtocolDecoder.java | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index c2146c22d..df0f1e2ed 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -113,17 +113,22 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { if (event.length() == 1) { char inputStatus = event.charAt(0); + String deviceModel = device.getModel(); if (inputStatus >= 'A' && inputStatus <= 'D') { int inputStatusInt = inputStatus - 'A'; - position.set(Position.PREFIX_IN + 1, BitUtil.check(inputStatusInt, 0)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(inputStatusInt, 1)); - position.set(Position.PREFIX_IN + 3, 0); + position.set(Position.PREFIX_IN + 1, (boolean) BitUtil.check(inputStatusInt, 0)); + position.set(Position.PREFIX_IN + 2, (boolean) BitUtil.check(inputStatusInt, 1)); + if (deviceModel == "SF-Lite") { + position.set(Position.PREFIX_IN + 3, false); + } return null; } else if (inputStatus >= 'O' && inputStatus <= 'R') { int inputStatusInt = inputStatus - 'O'; - position.set(Position.PREFIX_IN + 1, BitUtil.check(inputStatusInt, 0)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(inputStatusInt, 1)); - position.set(Position.PREFIX_IN + 3, 1); + position.set(Position.PREFIX_IN + 1, (boolean) BitUtil.check(inputStatusInt, 0)); + position.set(Position.PREFIX_IN + 2, (boolean) BitUtil.check(inputStatusInt, 1)); + if (deviceModel == "SF-Lite") { + position.set(Position.PREFIX_IN + 3, true); + } return null; } } @@ -247,7 +252,11 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_GPS, parser.nextInt()); position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001); - position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); + + String deviceModel = device.getModel(); + if (deviceModel == "AVL110" || deviceModel == "AVL120") { + position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); + } Integer lac = parser.nextHexInt(); Integer cid = parser.nextHexInt(); -- cgit v1.2.3 From 67f05acaa4e72db3576418a150ebbe53971309bf Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Sun, 9 Jul 2023 14:34:32 -0400 Subject: Fix some errors --- .../traccar/protocol/LaipacProtocolDecoder.java | 29 +++++++++++++--------- 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index df0f1e2ed..5218cfc16 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -109,16 +109,15 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeEvent(String event, Position position) { + private String decodeEvent(String event, Position position, String deviceModel) { if (event.length() == 1) { char inputStatus = event.charAt(0); - String deviceModel = device.getModel(); if (inputStatus >= 'A' && inputStatus <= 'D') { int inputStatusInt = inputStatus - 'A'; position.set(Position.PREFIX_IN + 1, (boolean) BitUtil.check(inputStatusInt, 0)); position.set(Position.PREFIX_IN + 2, (boolean) BitUtil.check(inputStatusInt, 1)); - if (deviceModel == "SF-Lite") { + if ("SF-Lite".equals(deviceModel)) { position.set(Position.PREFIX_IN + 3, false); } return null; @@ -126,7 +125,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { int inputStatusInt = inputStatus - 'O'; position.set(Position.PREFIX_IN + 1, (boolean) BitUtil.check(inputStatusInt, 0)); position.set(Position.PREFIX_IN + 2, (boolean) BitUtil.check(inputStatusInt, 1)); - if (deviceModel == "SF-Lite") { + if ("SF-Lite".equals(deviceModel)) { position.set(Position.PREFIX_IN + 3, true); } return null; @@ -220,15 +219,22 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { return null; } + String deviceId = parser.next(); + DeviceSession deviceSession = - getDeviceSession(channel, remoteAddress, parser.next()); + getDeviceSession(channel, remoteAddress, deviceId); if (deviceSession == null) { return null; } - Position position = new Position(getProtocolName()); + String deviceModel = null; + Device device = getCacheManager().getObject(Device.class, deviceId); + if (device != null) { + deviceModel = device.getModel(); + } - position.setDeviceId(deviceSession.getDeviceId()); + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceId); DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); @@ -247,14 +253,13 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { String event = parser.next(); position.set(Position.KEY_ALARM, decodeAlarm(event)); - position.set(Position.KEY_EVENT, decodeEvent(event, position)); + position.set(Position.KEY_EVENT, decodeEvent(event, position, deviceModel)); position.set(Position.KEY_BATTERY, Double.parseDouble(parser.next().replaceAll("\\.", "")) * 0.001); position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_GPS, parser.nextInt()); position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001); - - String deviceModel = device.getModel(); - if (deviceModel == "AVL110" || deviceModel == "AVL120") { + + if ("AVL110".equals(deviceModel) || "AVL120".equals(deviceModel)) { position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); } @@ -275,7 +280,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { sendAcknowledge(status, event, checksum, channel, remoteAddress); String devicePassword = AttributeUtil.getDevicePassword( - getCacheManager(), deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); + getCacheManager(), deviceId, getProtocolName(), DEFAULT_DEVICE_PASSWORD); sendEventResponse(event, devicePassword, channel, remoteAddress); } -- cgit v1.2.3 From e63b6bd4868f367c581db40997f741d00587b3b2 Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Sun, 9 Jul 2023 14:37:30 -0400 Subject: Fix more errors --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 5218cfc16..e3409c85a 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -28,6 +28,7 @@ import org.traccar.helper.PatternBuilder; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.Device; import org.traccar.helper.BitUtil; import java.net.SocketAddress; -- cgit v1.2.3 From 7ade92a97f41951aecfbb9de720780cf5232e2c1 Mon Sep 17 00:00:00 2001 From: edvalley <52469633+edvalley@users.noreply.github.com> Date: Sun, 9 Jul 2023 16:06:18 -0400 Subject: Fix more errors --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index e3409c85a..f0753cb5c 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -220,22 +220,21 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { return null; } - String deviceId = parser.next(); - DeviceSession deviceSession = - getDeviceSession(channel, remoteAddress, deviceId); + getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } String deviceModel = null; - Device device = getCacheManager().getObject(Device.class, deviceId); + Device device = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()); if (device != null) { deviceModel = device.getModel(); } Position position = new Position(getProtocolName()); - position.setDeviceId(deviceId); + + position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); @@ -281,7 +280,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { sendAcknowledge(status, event, checksum, channel, remoteAddress); String devicePassword = AttributeUtil.getDevicePassword( - getCacheManager(), deviceId, getProtocolName(), DEFAULT_DEVICE_PASSWORD); + getCacheManager(), deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); sendEventResponse(event, devicePassword, channel, remoteAddress); } -- cgit v1.2.3 From 779486a30483f7ab9c2c0f4c39c6a4e14319b330 Mon Sep 17 00:00:00 2001 From: Edward Valley Date: Sun, 9 Jul 2023 17:07:35 -0400 Subject: Fix more errors --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index f0753cb5c..de039a2fd 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -231,6 +231,9 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { if (device != null) { deviceModel = device.getModel(); } + if (deviceModel == null) { + deviceModel = ""; + } Position position = new Position(getProtocolName()); @@ -261,6 +264,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { if ("AVL110".equals(deviceModel) || "AVL120".equals(deviceModel)) { position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); + } else { + parser.next(); } Integer lac = parser.nextHexInt(); -- cgit v1.2.3 From 97240fd579c2d01f43a5b7ba1f9b16bad19085f2 Mon Sep 17 00:00:00 2001 From: Edward Valley Date: Sun, 9 Jul 2023 17:11:55 -0400 Subject: Remove unneded code --- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index de039a2fd..6a5b67669 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -231,9 +231,6 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { if (device != null) { deviceModel = device.getModel(); } - if (deviceModel == null) { - deviceModel = ""; - } Position position = new Position(getProtocolName()); -- cgit v1.2.3 From 60522a68d292541c44efa3736967f471d4347a50 Mon Sep 17 00:00:00 2001 From: Edward Valley Date: Sun, 9 Jul 2023 18:04:33 -0400 Subject: Follow refactor suggestion --- .../java/org/traccar/protocol/LaipacProtocolDecoder.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 6a5b67669..5745909c7 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -110,7 +110,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeEvent(String event, Position position, String deviceModel) { + private String decodeEvent(String event, Position position, String model) { if (event.length() == 1) { char inputStatus = event.charAt(0); @@ -118,7 +118,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { int inputStatusInt = inputStatus - 'A'; position.set(Position.PREFIX_IN + 1, (boolean) BitUtil.check(inputStatusInt, 0)); position.set(Position.PREFIX_IN + 2, (boolean) BitUtil.check(inputStatusInt, 1)); - if ("SF-Lite".equals(deviceModel)) { + if ("SF-Lite".equals(model)) { position.set(Position.PREFIX_IN + 3, false); } return null; @@ -126,7 +126,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { int inputStatusInt = inputStatus - 'O'; position.set(Position.PREFIX_IN + 1, (boolean) BitUtil.check(inputStatusInt, 0)); position.set(Position.PREFIX_IN + 2, (boolean) BitUtil.check(inputStatusInt, 1)); - if ("SF-Lite".equals(deviceModel)) { + if ("SF-Lite".equals(model)) { position.set(Position.PREFIX_IN + 3, true); } return null; @@ -226,11 +226,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { return null; } - String deviceModel = null; - Device device = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()); - if (device != null) { - deviceModel = device.getModel(); - } + String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); Position position = new Position(getProtocolName()); @@ -253,13 +249,13 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { String event = parser.next(); position.set(Position.KEY_ALARM, decodeAlarm(event)); - position.set(Position.KEY_EVENT, decodeEvent(event, position, deviceModel)); + position.set(Position.KEY_EVENT, decodeEvent(event, position, model)); position.set(Position.KEY_BATTERY, Double.parseDouble(parser.next().replaceAll("\\.", "")) * 0.001); position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_GPS, parser.nextInt()); position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001); - if ("AVL110".equals(deviceModel) || "AVL120".equals(deviceModel)) { + if ("AVL110".equals(model) || "AVL120".equals(model)) { position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); } else { parser.next(); -- cgit v1.2.3 From b5d5ec43181a428741c312462024d17ff7fbc676 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 11 Jul 2023 06:27:03 -0700 Subject: Fix services decoding --- .../java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index cd8d8e0cf..85589b064 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 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. @@ -148,7 +148,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedByte(); if (BitUtil.check(flags, 4)) { - sendResponse(channel, remoteAddress, index, type, buf); + sendResponse(channel, remoteAddress, index, type, buf.slice()); } if (type == MSG_DATA || type == MSG_SERVICES) { @@ -179,8 +179,9 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { case 0x01: deviceSession = getDeviceSession( channel, remoteAddress, buf.readCharSequence(15, StandardCharsets.US_ASCII).toString()); - - position.setDeviceId(deviceSession.getDeviceId()); + if (deviceSession == null) { + return null; + } break; case 0x02: long alarm = buf.readUnsignedIntLE(); -- cgit v1.2.3 From b3c6e22fc19ceeceb0f318131538b5e1d260450c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 12 Jul 2023 06:24:15 -0700 Subject: Ignore R31 alarm extension --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 5 ++++- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 5db06fc41..383d4cb3a 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -828,7 +828,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + short alarmExtension = buf.readUnsignedByte(); + if (variant != Variant.VXT01) { + position.set(Position.KEY_ALARM, decodeAlarm(alarmExtension)); + } } } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 04f41a5ee..fac92d70f 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -18,7 +18,7 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { "78780D01086471700328358100093F040D0A")); verifyAttribute(decoder, binary( - "78782416160501000221c0027c5e180c2b9c8d00150301cc002503002bde20050f01000004bd320d0a"), + "7878241617070a150e24ca01fba0040780e177005c0001720253360027db6204e40400004bf1e90d0a"), Position.KEY_ALARM, Position.ALARM_SOS); verifyAttribute(decoder, binary( -- cgit v1.2.3 From 7325030436e5fc42b6998240a0c5696a1d4fed5a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 12 Jul 2023 07:27:40 -0700 Subject: Fix GT06 transparent data --- src/main/java/org/traccar/helper/BufferUtil.java | 12 ++++++++++++ .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 17 ++++++----------- .../org/traccar/protocol/TeltonikaProtocolDecoder.java | 17 +++-------------- .../org/traccar/protocol/Gt06ProtocolDecoderTest.java | 13 +++++++++---- 4 files changed, 30 insertions(+), 29 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index d1025f548..12c31ba9d 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -71,4 +71,16 @@ public final class BufferUtil { } } + public static boolean isPrintable(ByteBuf buf, int length) { + boolean printable = true; + for (int i = 0; i < length; i++) { + byte b = buf.getByte(buf.readerIndex() + i); + if (b < 32 && b != '\r' && b != '\n') { + printable = false; + break; + } + } + return printable; + } + } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 383d4cb3a..e1bc2b5ad 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BufferUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -1382,19 +1383,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); buf.readUnsignedByte(); // external device type code - int length = buf.readableBytes() - 9; // line break + checksum + index + checksum + footer - if (length <= 0) { - return null; - } else if (length < 8) { - position.set( - Position.PREFIX_TEMP + 1, - Double.parseDouble(buf.readCharSequence(length - 1, StandardCharsets.US_ASCII).toString())); + ByteBuf data = buf.readSlice(buf.readableBytes() - 6); // index + checksum + footer + if (BufferUtil.isPrintable(data, data.readableBytes())) { + String value = data.readCharSequence(data.readableBytes(), StandardCharsets.US_ASCII).toString(); + position.set(Position.KEY_RESULT, value.trim()); } else { - buf.readUnsignedByte(); // card type - position.set( - Position.KEY_DRIVER_UNIQUE_ID, - buf.readCharSequence(length - 1, StandardCharsets.US_ASCII).toString()); + position.set(Position.KEY_RESULT, ByteBufUtil.hexDump(data)); } return position; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index c8e0005f9..e888642b4 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BufferUtil; import org.traccar.model.Device; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; @@ -112,18 +113,6 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private boolean isPrintable(ByteBuf buf, int length) { - boolean printable = true; - for (int i = 0; i < length; i++) { - byte b = buf.getByte(buf.readerIndex() + i); - if (b < 32 && b != '\r' && b != '\n') { - printable = false; - break; - } - } - return printable; - } - private void decodeSerial( Channel channel, SocketAddress remoteAddress, DeviceSession deviceSession, Position position, ByteBuf buf) { @@ -169,7 +158,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_TYPE, type); int length = buf.readInt(); - if (isPrintable(buf, length)) { + if (BufferUtil.isPrintable(buf, length)) { String data = buf.readSlice(length).toString(StandardCharsets.US_ASCII).trim(); if (data.startsWith("UUUUww") && data.endsWith("SSS")) { String[] values = data.substring(6, data.length() - 4).split(";"); @@ -636,7 +625,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // type int length = buf.readInt() - 4; getLastLocation(position, new Date(buf.readUnsignedInt() * 1000)); - if (isPrintable(buf, length)) { + if (BufferUtil.isPrintable(buf, length)) { String data = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString().trim(); if (data.startsWith("GTSL")) { position.set(Position.KEY_DRIVER_UNIQUE_ID, data.split("\\|")[4]); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index fac92d70f..26f300554 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + /*verifyAttribute(decoder, binary( + "797900109b0344373532304136320d0a000f87f00d0a"), + Position.KEY_DRIVER_UNIQUE_ID, "44373532304136320d0a");*/ + verifyAttribute(decoder, binary( "7878241617070a150e24ca01fba0040780e177005c0001720253360027db6204e40400004bf1e90d0a"), Position.KEY_ALARM, Position.ALARM_SOS); @@ -111,8 +115,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { "7878281520000000003c49434349443a38393838323339303030303039373330323635303e00020d446f260d0a"), Position.KEY_ICCID, "89882390000097302650"); - verifyNull(decoder, binary( - "797900099b0380d600046f91e90d0a")); + verifyAttribute(decoder, binary( + "797900099b0380d600046f91e90d0a"), + Position.KEY_RESULT, "80d600"); verifyNull(decoder, binary( "797900a56615010d081f3b012c323131303d30303033643238342c323130353d30303030316332302c323130623d30303030326537632c323130633d30303033643238342c323130663d30303030306331632c323130643d30303030323166632c323161363d30303030303030302c323130343d30303030306531302c323132663d30303030303030302c323134353d30303030303030302ccb03851f5f03c020525514a7003e216a0d0a")); @@ -125,7 +130,7 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyAttribute(decoder, binary( "7979000E9B0332382E33A1E60D0A0289BE490D0A"), - Position.PREFIX_TEMP + 1, 28.3); + Position.KEY_RESULT, "32382e33a1e60d0a"); verifyPosition(decoder, binary( "7878353714080d05000ac500a886eb0b7522f000100001fe0a05ea004f1b000001002e0400002328003b0217c0003c0401020001002c468a0d0a")); @@ -168,7 +173,7 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyAttribute(decoder, binary( "797900149b03023539303042343843454238410300139ba40d0a"), - Position.KEY_DRIVER_UNIQUE_ID, "5900B48CEB"); + Position.KEY_RESULT, "0235393030423438434542384103"); verifyPosition(decoder, binary( "787821121303120b2524c70138e363085b549003d43301940057d200cd52c000006aa1ca0d0a")); -- cgit v1.2.3 From 2be2a4558ace9825a69aecf6329305490eb5fe5e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 12 Jul 2023 07:44:58 -0700 Subject: Support JM-VL03 messages --- .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 14 ++++++++++---- .../java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 7 +++++-- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index e1bc2b5ad..f7cdd3920 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -96,7 +96,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_INFO = 0x94; public static final int MSG_SERIAL = 0x9B; public static final int MSG_STRING_INFO = 0x21; - public static final int MSG_GPS_2 = 0xA0; // GK310 + public static final int MSG_GPS_LBS_7 = 0xA0; // GK310 & JM-VL03 public static final int MSG_LBS_2 = 0xA1; // GK310 public static final int MSG_WIFI_3 = 0xA2; // GK310 public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 @@ -170,7 +170,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_4: case MSG_GPS_PHONE: case MSG_GPS_LBS_EXTEND: - case MSG_GPS_2: + case MSG_GPS_LBS_7: case MSG_FENCE_SINGLE: case MSG_FENCE_MULTI: return true; @@ -192,7 +192,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: - case MSG_GPS_2: + case MSG_GPS_LBS_7: case MSG_FENCE_SINGLE: case MSG_FENCE_MULTI: case MSG_LBS_ALARM: @@ -351,7 +351,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { lac = buf.readUnsignedShort(); } long cid; - if (type == MSG_LBS_ALARM) { + if (type == MSG_LBS_ALARM || type == MSG_GPS_LBS_7) { cid = buf.readLong(); } else if (type == MSG_GPS_LBS_6) { cid = buf.readUnsignedInt(); @@ -919,6 +919,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } + if (type == MSG_GPS_LBS_7) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + buf.readUnsignedByte(); // upload mode + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0 ? true : null); + } + if (buf.readableBytes() == 4 + 6) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 26f300554..cc71eb9bd 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,9 +17,12 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); - /*verifyAttribute(decoder, binary( + verifyNotNull(decoder, binary( + "787829a0170704112226cf0163fe7c0420f6f000091302d402000091290000000007186b8f01030001460d010d0a")); + + verifyAttribute(decoder, binary( "797900109b0344373532304136320d0a000f87f00d0a"), - Position.KEY_DRIVER_UNIQUE_ID, "44373532304136320d0a");*/ + Position.KEY_RESULT, "D7520A62"); verifyAttribute(decoder, binary( "7878241617070a150e24ca01fba0040780e177005c0001720253360027db6204e40400004bf1e90d0a"), -- cgit v1.2.3 From 105873ab5256a774ef07ca7ee459da0917829591 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Jul 2023 07:00:45 -0700 Subject: Add Eview Pet result support --- .../traccar/protocol/Minifinder2ProtocolDecoder.java | 17 +++++++++++++++++ .../protocol/Minifinder2ProtocolDecoderTest.java | 5 +++++ 2 files changed, 22 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 85589b064..6289bd2eb 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -324,6 +324,23 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { return positions; + } else if (type == MSG_RESPONSE) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + buf.readUnsignedByte(); // length + position.set(Position.KEY_RESULT, String.valueOf(buf.readUnsignedByte())); + + return position; + } return null; diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index 587a520d1..64d245a8e 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class Minifinder2ProtocolDecoderTest extends ProtocolTest { @@ -14,6 +15,10 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { "ab101c00d6f61e000110013836333932313033393939363038300937efd201640c000000"), "barkCount", 12L); + verifyAttribute(decoder, binary( + "ab00030008c700007f0100"), + Position.KEY_RESULT, "0"); + verifyAttribute(decoder, binary( "ab102600080f1400011001383633393231303339393833343736092429b347633003a96409020000008027b34763"), "bark", true); -- cgit v1.2.3 From bd64dc0bc759e8325f09686909c25f3a08fbf686 Mon Sep 17 00:00:00 2001 From: Rodolfo Silva Date: Thu, 13 Jul 2023 14:26:34 -0300 Subject: AMQP Forwarder Add support to forward events and positions to AMQP (RabbitMQ). --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 6 ++ src/main/java/org/traccar/config/Keys.java | 20 +++++- .../org/traccar/forward/EventForwarderAmqp.java | 81 ++++++++++++++++++++++ .../org/traccar/forward/PositionForwarderAmqp.java | 80 +++++++++++++++++++++ 5 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/traccar/forward/EventForwarderAmqp.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarderAmqp.java (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index b4e11ed98..d08dfebc5 100644 --- a/build.gradle +++ b/build.gradle @@ -89,6 +89,7 @@ dependencies { implementation "redis.clients:jedis:4.4.1" implementation "com.google.firebase:firebase-admin:9.1.1" implementation "com.nimbusds:oauth2-oidc-sdk:10.9.1" + implementation "com.rabbitmq:amqp-client:5.18.0" testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" testImplementation "org.junit.jupiter:junit-jupiter-engine:$junitVersion" testImplementation "org.mockito:mockito-core:5.3.1" diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b7bdbc6bf..f5db75846 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -37,10 +37,12 @@ import org.traccar.database.OpenIdProvider; import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; +import org.traccar.forward.EventForwarderAmqp; import org.traccar.forward.EventForwarderKafka; import org.traccar.forward.EventForwarderMqtt; import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; +import org.traccar.forward.PositionForwarderAmqp; import org.traccar.forward.PositionForwarderKafka; import org.traccar.forward.PositionForwarderRedis; import org.traccar.forward.PositionForwarderUrl; @@ -360,6 +362,8 @@ public class MainModule extends AbstractModule { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { String forwardType = config.getString(Keys.EVENT_FORWARD_TYPE); switch (forwardType) { + case "amqp": + return new EventForwarderAmqp(config, objectMapper); case "kafka": return new EventForwarderKafka(config, objectMapper); case "mqtt": @@ -379,6 +383,8 @@ public class MainModule extends AbstractModule { switch (config.getString(Keys.FORWARD_TYPE)) { case "json": return new PositionForwarderJson(config, client, objectMapper); + case "amqp": + return new PositionForwarderAmqp(config, objectMapper); case "kafka": return new PositionForwarderKafka(config, objectMapper); case "redis": diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6f5360c22..314ac0df2 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -837,7 +837,15 @@ public final class Keys { "url"); /** - * Position forwarding Kafka topic. + * Position forwarding AMQP exchange. + */ + public static final ConfigKey FORWARD_EXCHANGE = new StringConfigKey( + "forward.exchange", + List.of(KeyType.CONFIG), + "traccar"); + + /** + * Position forwarding Kafka topic or AQMP Routing Key. */ public static final ConfigKey FORWARD_TOPIC = new StringConfigKey( "forward.topic", @@ -906,7 +914,15 @@ public final class Keys { "json"); /** - * Events forwarding Kafka topic. + * Events forwarding AMQP exchange. + */ + public static final ConfigKey EVENT_FORWARD_EXCHANGE = new StringConfigKey( + "event.forward.exchange", + List.of(KeyType.CONFIG), + "traccar"); + + /** + * Events forwarding Kafka topic or AQMP Routing Key. */ public static final ConfigKey EVENT_FORWARD_TOPIC = new StringConfigKey( "event.forward.topic", diff --git a/src/main/java/org/traccar/forward/EventForwarderAmqp.java b/src/main/java/org/traccar/forward/EventForwarderAmqp.java new file mode 100644 index 000000000..64edbe8a5 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarderAmqp.java @@ -0,0 +1,81 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.rabbitmq.client.AMQP.BasicProperties; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Properties; +import java.util.concurrent.TimeoutException; + +public class EventForwarderAmqp implements EventForwarder { + + private final Channel channel; + private final ObjectMapper objectMapper; + + private final String exchange; + private final String topic; + + public EventForwarderAmqp(Config config, ObjectMapper objectMapper) { + ConnectionFactory factory = new ConnectionFactory(); + try { + factory.setUri(config.getString(Keys.EVENT_FORWARD_URL)); + } catch (NoSuchAlgorithmException | URISyntaxException | KeyManagementException e) { + throw new RuntimeException(e); + } + + try { + Connection connection = factory.newConnection(); + exchange = config.getString(Keys.EVENT_FORWARD_EXCHANGE); + topic = config.getString(Keys.EVENT_FORWARD_TOPIC); + channel = connection.createChannel(); + channel.exchangeDeclare(exchange, "topic", true); + this.objectMapper = objectMapper; + } catch (IOException | TimeoutException e) { + throw new RuntimeException(e); + } + } + + @Override + public void forward(EventData eventData, ResultHandler resultHandler) { + try { + String value = objectMapper.writeValueAsString(eventData); + + BasicProperties properties = new BasicProperties.Builder() + .contentType("application/json") + .contentEncoding("string") + .deliveryMode(2) + .priority(10) + .build(); + + channel.basicPublish(exchange, topic, properties, value.getBytes()); + resultHandler.onResult(true, null); + } catch (IOException e) { + resultHandler.onResult(false, e); + } + } +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderAmqp.java b/src/main/java/org/traccar/forward/PositionForwarderAmqp.java new file mode 100644 index 000000000..c55ca3d73 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderAmqp.java @@ -0,0 +1,80 @@ +/* + * 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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.rabbitmq.client.AMQP.BasicProperties; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Properties; +import java.util.concurrent.TimeoutException; + +public class PositionForwarderAmqp implements PositionForwarder { + + private final Channel channel; + private final ObjectMapper objectMapper; + + private final String exchange; + private final String topic; + + public PositionForwarderAmqp(Config config, ObjectMapper objectMapper) { + ConnectionFactory factory = new ConnectionFactory(); + try { + factory.setUri(config.getString(Keys.FORWARD_URL)); + } catch (NoSuchAlgorithmException | URISyntaxException | KeyManagementException e) { + throw new RuntimeException(e); + } + + try { + Connection connection = factory.newConnection(); + topic = config.getString(Keys.FORWARD_TOPIC); + exchange = config.getString(Keys.EVENT_FORWARD_EXCHANGE); + channel = connection.createChannel(); + channel.exchangeDeclare(exchange, "topic", true); + this.objectMapper = objectMapper; + } catch (IOException | TimeoutException e) { + throw new RuntimeException(e); + } + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + try { + String value = objectMapper.writeValueAsString(positionData); + + BasicProperties properties = new BasicProperties.Builder() + .contentType("application/json") + .contentEncoding("string") + .deliveryMode(2) + .priority(10) + .build(); + + channel.basicPublish(exchange, topic, properties, value.getBytes()); + resultHandler.onResult(true, null); + } catch (IOException e) { + resultHandler.onResult(false, e); + } + } +} -- cgit v1.2.3 From 104e8a4a7829b4b4a4723a715cc2b15899fa8b9f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 14 Jul 2023 06:49:08 -0700 Subject: Option to disable Topic commands --- src/main/java/org/traccar/config/Keys.java | 7 +++++++ src/main/java/org/traccar/protocol/TopinProtocol.java | 9 ++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6f5360c22..7ad981799 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -233,6 +233,13 @@ public final class Keys { ".includeTemp", List.of(KeyType.CONFIG, KeyType.DEVICE)); + /** + * Disable commands for the protocol. Not all protocols support this option. + */ + public static final ConfigSuffix PROTOCOL_DISABLE_COMMANDS = new BooleanConfigSuffix( + ".disableCommands", + List.of(KeyType.CONFIG)); + /** * Protocol format. Used by protocols that have configurable message format. */ diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index b15373d71..37afac582 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocol.java +++ b/src/main/java/org/traccar/protocol/TopinProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 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 org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Command; import javax.inject.Inject; @@ -27,8 +28,10 @@ public class TopinProtocol extends BaseProtocol { @Inject public TopinProtocol(Config config) { - setSupportedDataCommands( - Command.TYPE_SOS_NUMBER); + if (!config.getBoolean(Keys.PROTOCOL_DISABLE_COMMANDS.withPrefix(getName()))) { + setSupportedDataCommands( + Command.TYPE_SOS_NUMBER); + } addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { -- cgit v1.2.3 From 007b4007e063cfb966a4024ef267992a4f1f9ccb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 14 Jul 2023 07:41:31 -0700 Subject: Trackology Tracker Type-A protocol --- src/main/java/org/traccar/protocol/TopinProtocolDecoder.java | 7 ++++++- src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index a1d5481db..b5dd3c4b9 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -48,7 +48,11 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS = 0x10; public static final int MSG_GPS_OFFLINE = 0x11; public static final int MSG_STATUS = 0x13; + public static final int MSG_SLEEP = 0x14; + public static final int MSG_FACTORY_RESET = 0x15; public static final int MSG_WIFI_OFFLINE = 0x17; + public static final int MSG_LBS_WIFI = 0x18; + public static final int MSG_LBS_WIFI_OFFLINE = 0x19; public static final int MSG_TIME_UPDATE = 0x30; public static final int MSG_SOS_NUMBER = 0x41; public static final int MSG_WIFI = 0x69; @@ -216,7 +220,8 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type == MSG_WIFI || type == MSG_WIFI_OFFLINE) { + } else if (type == MSG_WIFI || type == MSG_WIFI_OFFLINE + || type == MSG_LBS_WIFI || type == MSG_LBS_WIFI_OFFLINE) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java index 763c4f2da..b55e12e9d 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class TopinProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780d0103593390754169634d0d0a")); + verifyNotNull(decoder, binary( + "787803181604130318491475905bd30e25001e10bbf7635d14759006e626560401cc00000028660090df425f000028660090df576c00002866009487566700002866009ca15667000d0a")); + verifyAttribute(decoder, binary( "7878006921120412565802010601071e4a9764071e4a9864010d0a"), Position.KEY_ALARM, Position.ALARM_VIBRATION); -- cgit v1.2.3 From 74d73a9dc28fc608117c04da4652d43f633a72c5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 16 Jul 2023 08:02:56 -0700 Subject: Improve user check --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 38bf48f30..7f5a46225 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -181,7 +181,7 @@ public class PermissionsService { || before.getUserLimit() != after.getUserLimit()) { checkAdmin(userId); } - User user = getUser(userId); + User user = userId > 0 ? getUser(userId) : null; if (user != null && user.getExpirationTime() != null && !Objects.equals(before.getExpirationTime(), after.getExpirationTime()) && (after.getExpirationTime() == null -- cgit v1.2.3 From 3642b952086355f5f2a52f7dc9b2cdfea4c02e31 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jul 2023 21:00:44 -0700 Subject: Handle HS-5000 cell id --- src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 2fb7c6e92..1ad27be5f 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -284,7 +284,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { String[] values = cell.split("@"); network.addCellTower(CellTower.from( Integer.parseInt(values[0]), Integer.parseInt(values[1]), - Integer.parseInt(values[2], 16), Integer.parseInt(values[3], 16))); + Integer.parseInt(values[2], 16), Long.parseLong(values[3], 16))); } break; case 0x0021: diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java index fe4b077c6..a54fa53c6 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java @@ -31,6 +31,9 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest { "c000000049aa0000000000028e8800000032303038323630373534323800e1d47fffcd163d0000000000f30000000100157703f8000046000000000aade0ffffffff0011000800000496c0"), Position.KEY_HOURS, 58.7); + verifyNotNull(decoder, binary( + "c0000000b1aa000000000000050000000031393730303130313134303200000000000000000000000000000000000100180000000000000000000000000000000000c57e000005000a1a000000c569000900155756575a5a5a43445a4e57313139313534000f00133836393733313035313339393231300010000c302e30303030303000110008000000000014000bf800002800000000150006000000200016353035403031403040313337313931363831c0")); + verifyNotNull(decoder, binary( "c000000077aa00000000000070020000003230303132373035313635330000000000000000000000000000000000010015ffffffff000000000000019dffffffffff0005000a1f00000e455a00200019313238354031406666666540386233663930634030000f0013333536373236313038313335343530c0")); -- cgit v1.2.3 From 548b19193febdd7e53e4e42014ad46235866de58 Mon Sep 17 00:00:00 2001 From: Jacob Schooley Date: Tue, 18 Jul 2023 23:45:42 -0400 Subject: Set session cookie max age if web.sessionTimeout is set --- src/main/java/org/traccar/web/WebServer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index b5d2f2771..184c546d5 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -193,14 +193,16 @@ public class WebServer implements LifecycleObject { sessionHandler.setSessionCache(sessionCache); } + SessionCookieConfig sessionCookieConfig = servletHandler.getServletContext().getSessionCookieConfig(); + int sessionTimeout = config.getInteger(Keys.WEB_SESSION_TIMEOUT); if (sessionTimeout > 0) { servletHandler.getSessionHandler().setMaxInactiveInterval(sessionTimeout); + sessionCookieConfig.setMaxAge(sessionTimeout); } String sameSiteCookie = config.getString(Keys.WEB_SAME_SITE_COOKIE); if (sameSiteCookie != null) { - SessionCookieConfig sessionCookieConfig = servletHandler.getServletContext().getSessionCookieConfig(); switch (sameSiteCookie.toLowerCase()) { case "lax": sessionCookieConfig.setComment(HttpCookie.SAME_SITE_LAX_COMMENT); -- cgit v1.2.3 From 5a1a8d9192ee44b116f10e5ce3551a4e4bc70deb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2023 06:26:19 -0700 Subject: Fix date decoding --- src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java | 2 +- .../java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java index 27b7baf54..9e64ec9be 100644 --- a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java @@ -94,7 +94,7 @@ public class T622IridiumProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(buf.readIntLE() / 1000000.0); break; case 0x04: - position.setTime(new Date((buf.readUnsignedIntLE() + 946713600) * 1000)); + position.setTime(new Date((buf.readUnsignedIntLE() + 946684800) * 1000)); break; case 0x05: position.setValid(buf.readUnsignedByte() > 0); diff --git a/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java index 17b252618..ff5d5b0a0 100644 --- a/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T622IridiumProtocolDecoderTest.java @@ -1,12 +1,10 @@ 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 { @@ -15,7 +13,8 @@ public class T622IridiumProtocolDecoderTest extends ProtocolTest { decoder.setFormat("01,02,03,04,05,08"); verifyPosition(decoder, binary( - "01003301001c2a8cef8333303034333430363735343836353000001700006461d512020011232f03a0fff1c85d0612b3f02b00000048")); + "01003501001c68b2cb1733303034333430363735343836353000016e000064b5f497020013234c5ea0ff1c365d0600b1482c010000cf0004"), + position("2023-07-18 02:10:08.000", true, -6.26732, 106.77200)); } -- cgit v1.2.3 From dcef13b1fc7cf052463e11532365b3ad1f948b99 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2023 07:45:13 -0700 Subject: Trim important fields --- src/main/java/org/traccar/model/Device.java | 4 ++-- src/main/java/org/traccar/model/Driver.java | 2 +- src/main/java/org/traccar/model/User.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 2c582328e..c259e1413 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -53,7 +53,7 @@ public class Device extends GroupedModel implements Disableable, Schedulable { } public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId; + this.uniqueId = uniqueId != null ? uniqueId.trim() : null; } public static final String STATUS_UNKNOWN = "unknown"; @@ -100,7 +100,7 @@ public class Device extends GroupedModel implements Disableable, Schedulable { } public void setPhone(String phone) { - this.phone = phone; + this.phone = phone != null ? phone.trim() : null; } private String model; diff --git a/src/main/java/org/traccar/model/Driver.java b/src/main/java/org/traccar/model/Driver.java index b9e023088..2689c67f2 100644 --- a/src/main/java/org/traccar/model/Driver.java +++ b/src/main/java/org/traccar/model/Driver.java @@ -38,7 +38,7 @@ public class Driver extends ExtendedModel { } public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId; + this.uniqueId = uniqueId != null ? uniqueId.trim() : null; } } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 53594fe07..0540f16d7 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -63,7 +63,7 @@ public class User extends ExtendedModel implements UserRestrictions, Disableable } public void setPhone(String phone) { - this.phone = phone; + this.phone = phone != null ? phone.trim() : null; } private boolean readonly; -- cgit v1.2.3 From 840d5600c69839e9be7a241d69005f322dfef124 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2023 07:46:04 -0700 Subject: Remove unnecessary checks --- src/main/java/org/traccar/model/Device.java | 2 +- src/main/java/org/traccar/model/Driver.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index c259e1413..e07815976 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -53,7 +53,7 @@ public class Device extends GroupedModel implements Disableable, Schedulable { } public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId != null ? uniqueId.trim() : null; + this.uniqueId = uniqueId.trim(); } public static final String STATUS_UNKNOWN = "unknown"; diff --git a/src/main/java/org/traccar/model/Driver.java b/src/main/java/org/traccar/model/Driver.java index 2689c67f2..ca5714e51 100644 --- a/src/main/java/org/traccar/model/Driver.java +++ b/src/main/java/org/traccar/model/Driver.java @@ -38,7 +38,7 @@ public class Driver extends ExtendedModel { } public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId != null ? uniqueId.trim() : null; + this.uniqueId = uniqueId.trim(); } } -- cgit v1.2.3 From 8970e5ad49cbe9ad2ec106b2140cfc9f276ef7de Mon Sep 17 00:00:00 2001 From: Rodolfo Silva Date: Wed, 19 Jul 2023 21:38:33 -0300 Subject: change the year from the copyright text --- src/main/java/org/traccar/forward/EventForwarderAmqp.java | 2 +- src/main/java/org/traccar/forward/PositionForwarderAmqp.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/EventForwarderAmqp.java b/src/main/java/org/traccar/forward/EventForwarderAmqp.java index 64edbe8a5..97f14d4ea 100644 --- a/src/main/java/org/traccar/forward/EventForwarderAmqp.java +++ b/src/main/java/org/traccar/forward/EventForwarderAmqp.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 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. diff --git a/src/main/java/org/traccar/forward/PositionForwarderAmqp.java b/src/main/java/org/traccar/forward/PositionForwarderAmqp.java index c55ca3d73..ea9e5c370 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderAmqp.java +++ b/src/main/java/org/traccar/forward/PositionForwarderAmqp.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 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. -- cgit v1.2.3 From dacaefcd4e416eeeedf1074729a8670aec1e53fb Mon Sep 17 00:00:00 2001 From: Rodolfo Silva Date: Wed, 19 Jul 2023 22:42:16 -0300 Subject: refactor the amqp client logic to have a separated class --- src/main/java/org/traccar/forward/AmqpClient.java | 57 ++++++++++++++++++++++ .../org/traccar/forward/EventForwarderAmqp.java | 49 +++---------------- .../org/traccar/forward/PositionForwarderAmqp.java | 48 +++--------------- 3 files changed, 73 insertions(+), 81 deletions(-) create mode 100644 src/main/java/org/traccar/forward/AmqpClient.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/AmqpClient.java b/src/main/java/org/traccar/forward/AmqpClient.java new file mode 100644 index 000000000..302aa664c --- /dev/null +++ b/src/main/java/org/traccar/forward/AmqpClient.java @@ -0,0 +1,57 @@ +/* + * 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.forward; + +import com.rabbitmq.client.BuiltinExchangeType; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import com.rabbitmq.client.MessageProperties; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.concurrent.TimeoutException; + +public class AmqpClient { + private final Channel channel; + private final String exchange; + private final String topic; + + AmqpClient(String connectionUrl, String exchange, String topic) { + this.exchange = exchange; + this.topic = topic; + + ConnectionFactory factory = new ConnectionFactory(); + try { + factory.setUri(connectionUrl); + } catch (NoSuchAlgorithmException | URISyntaxException | KeyManagementException e) { + throw new RuntimeException("Error while setting URI for RabbitMQ connection factory", e); + } + + try (Connection connection = factory.newConnection()) { + channel = connection.createChannel(); + channel.exchangeDeclare(exchange, BuiltinExchangeType.TOPIC, true); + } catch (IOException | TimeoutException e) { + throw new RuntimeException("Error while creating and configuring RabbitMQ channel", e); + } + } + + public void publishMessage(String message) throws IOException { + channel.basicPublish(exchange, topic, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); + } +} diff --git a/src/main/java/org/traccar/forward/EventForwarderAmqp.java b/src/main/java/org/traccar/forward/EventForwarderAmqp.java index 97f14d4ea..5c38a4459 100644 --- a/src/main/java/org/traccar/forward/EventForwarderAmqp.java +++ b/src/main/java/org/traccar/forward/EventForwarderAmqp.java @@ -15,64 +15,31 @@ */ package org.traccar.forward; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.rabbitmq.client.AMQP.BasicProperties; -import com.rabbitmq.client.Channel; -import com.rabbitmq.client.Connection; -import com.rabbitmq.client.ConnectionFactory; + import org.traccar.config.Config; import org.traccar.config.Keys; import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.Properties; -import java.util.concurrent.TimeoutException; public class EventForwarderAmqp implements EventForwarder { - private final Channel channel; + private final AmqpClient amqpClient; private final ObjectMapper objectMapper; - private final String exchange; - private final String topic; - public EventForwarderAmqp(Config config, ObjectMapper objectMapper) { - ConnectionFactory factory = new ConnectionFactory(); - try { - factory.setUri(config.getString(Keys.EVENT_FORWARD_URL)); - } catch (NoSuchAlgorithmException | URISyntaxException | KeyManagementException e) { - throw new RuntimeException(e); - } - - try { - Connection connection = factory.newConnection(); - exchange = config.getString(Keys.EVENT_FORWARD_EXCHANGE); - topic = config.getString(Keys.EVENT_FORWARD_TOPIC); - channel = connection.createChannel(); - channel.exchangeDeclare(exchange, "topic", true); - this.objectMapper = objectMapper; - } catch (IOException | TimeoutException e) { - throw new RuntimeException(e); - } + String connectionUrl = config.getString(Keys.EVENT_FORWARD_URL); + String exchange = config.getString(Keys.EVENT_FORWARD_EXCHANGE); + String topic = config.getString(Keys.EVENT_FORWARD_TOPIC); + this.objectMapper = objectMapper; + amqpClient = new AmqpClient(connectionUrl, exchange, topic); } @Override public void forward(EventData eventData, ResultHandler resultHandler) { try { String value = objectMapper.writeValueAsString(eventData); - - BasicProperties properties = new BasicProperties.Builder() - .contentType("application/json") - .contentEncoding("string") - .deliveryMode(2) - .priority(10) - .build(); - - channel.basicPublish(exchange, topic, properties, value.getBytes()); + amqpClient.publishMessage(value); resultHandler.onResult(true, null); } catch (IOException e) { resultHandler.onResult(false, e); diff --git a/src/main/java/org/traccar/forward/PositionForwarderAmqp.java b/src/main/java/org/traccar/forward/PositionForwarderAmqp.java index ea9e5c370..3996bda15 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderAmqp.java +++ b/src/main/java/org/traccar/forward/PositionForwarderAmqp.java @@ -15,63 +15,31 @@ */ package org.traccar.forward; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.rabbitmq.client.AMQP.BasicProperties; -import com.rabbitmq.client.Channel; -import com.rabbitmq.client.Connection; -import com.rabbitmq.client.ConnectionFactory; + import org.traccar.config.Config; import org.traccar.config.Keys; import java.io.IOException; -import java.net.URISyntaxException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.Properties; -import java.util.concurrent.TimeoutException; public class PositionForwarderAmqp implements PositionForwarder { - private final Channel channel; + private final AmqpClient amqpClient; private final ObjectMapper objectMapper; - private final String exchange; - private final String topic; - public PositionForwarderAmqp(Config config, ObjectMapper objectMapper) { - ConnectionFactory factory = new ConnectionFactory(); - try { - factory.setUri(config.getString(Keys.FORWARD_URL)); - } catch (NoSuchAlgorithmException | URISyntaxException | KeyManagementException e) { - throw new RuntimeException(e); - } - - try { - Connection connection = factory.newConnection(); - topic = config.getString(Keys.FORWARD_TOPIC); - exchange = config.getString(Keys.EVENT_FORWARD_EXCHANGE); - channel = connection.createChannel(); - channel.exchangeDeclare(exchange, "topic", true); - this.objectMapper = objectMapper; - } catch (IOException | TimeoutException e) { - throw new RuntimeException(e); - } + String connectionUrl = config.getString(Keys.FORWARD_URL); + String exchange = config.getString(Keys.FORWARD_EXCHANGE); + String topic = config.getString(Keys.FORWARD_TOPIC); + amqpClient = new AmqpClient(connectionUrl, exchange, topic); + this.objectMapper = objectMapper; } @Override public void forward(PositionData positionData, ResultHandler resultHandler) { try { String value = objectMapper.writeValueAsString(positionData); - - BasicProperties properties = new BasicProperties.Builder() - .contentType("application/json") - .contentEncoding("string") - .deliveryMode(2) - .priority(10) - .build(); - - channel.basicPublish(exchange, topic, properties, value.getBytes()); + amqpClient.publishMessage(value); resultHandler.onResult(true, null); } catch (IOException e) { resultHandler.onResult(false, e); -- cgit v1.2.3 From 6631d7c4b3522e81af563e3ac82131a6e5c50b89 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Jul 2023 06:48:50 -0700 Subject: Improve RF-V48 frame decoding --- .../java/org/traccar/protocol/WatchFrameDecoder.java | 16 ++++++++++++++-- .../java/org/traccar/protocol/WatchFrameDecoderTest.java | 4 ++++ 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchFrameDecoder.java b/src/main/java/org/traccar/protocol/WatchFrameDecoder.java index ec67aa34d..9dfae8726 100644 --- a/src/main/java/org/traccar/protocol/WatchFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchFrameDecoder.java @@ -27,9 +27,21 @@ public class WatchFrameDecoder extends BaseFrameDecoder { protected Object decode( ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + int brackets = 0; int endIndex = -1; - for (int i = buf.writerIndex() - 1; i >= buf.readerIndex(); i--) { - if (buf.getByte(i) == ']') { + for (int i = buf.readerIndex(); i < buf.writerIndex(); i++) { + byte b = buf.getByte(i); + switch (b) { + case '[': + brackets += 1; + break; + case ']': + brackets -= 1; + break; + default: + break; + } + if (brackets == 0 && i > buf.readerIndex()) { endIndex = i + 1; break; } diff --git a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java index bf212544c..cb20e1b4d 100644 --- a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java @@ -10,6 +10,10 @@ public class WatchFrameDecoderTest extends ProtocolTest { var decoder = inject(new WatchFrameDecoder()); + verifyFrame( + binary("5b33472a393730353134313734302a303030392a4c4b2c302c302c35335d"), + decoder.decode(null, null, binary("5b33472a393730353134313734302a303030392a4c4b2c302c302c35335d5b33472a393730353134313734302a303035412a55442c3139303732332c3139303730372c412c33362e3831353130392c4e2c31302e313739323331322c452c382e32342c3132372e392c32312e302c352c3130302c35332c302c302c30303030303030302c302c302c35382e305d5b33472a393730353134313734302a303030332a544b515d5b33472a393730353134313734302a303030392a4c4b2c302c302c35335d"))); + verifyFrame( binary("5b33472a3838303930303234322a303133442a55442c3132303632332c3134303032302c412c34382e3934393237332c4e2c20342e333738333036302c452c31382e35362c34332e382c302e302c31322c3130302c37362c3232363132302c302c30303030303030302c322c3235352c3230342c382c333131302c35353032352c3134362c333133302c34393239372c3132342c352c42616e67696e67576966692c33343a61313a65643a65313a39313a34662c2d37312c42415220576946692c33363a61323a65313a65643a61313a64652c2d37322c4e6574776f726b576966692c32363a64653a61313a65643a65313a61302c2d37332c46696265722c33363a61313a65643a65313a39313a34662c2d37352c5b4c475f57616c6c2d4d6f756e7420412f435d653732352c36363a61313a65643a65313a65373a32352c2d38322c31352e305d"), decoder.decode(null, null, binary("5b33472a3838303930303234322a303133442a55442c3132303632332c3134303032302c412c34382e3934393237332c4e2c20342e333738333036302c452c31382e35362c34332e382c302e302c31322c3130302c37362c3232363132302c302c30303030303030302c322c3235352c3230342c382c333131302c35353032352c3134362c333133302c34393239372c3132342c352c42616e67696e67576966692c33343a61313a65643a65313a39313a34662c2d37312c42415220576946692c33363a61323a65313a65643a61313a64652c2d37322c4e6574776f726b576966692c32363a64653a61313a65643a65313a61302c2d37332c46696265722c33363a61313a65643a65313a39313a34662c2d37352c5b4c475f57616c6c2d4d6f756e7420412f435d653732352c36363a61313a65643a65313a65373a32352c2d38322c31352e305d"))); -- cgit v1.2.3 From c85df48c0ff76979839f62120fd311073e0c1d80 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 21 Jul 2023 07:39:24 -0700 Subject: Fix Fifotrack Q3 missing time --- src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java | 2 ++ src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index c30398d36..87587aa1e 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -242,6 +242,8 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { } else { + getLastLocation(position, position.getDeviceTime()); + String[] points = parser.next().split("\\|"); for (String point : points) { String[] wifi = point.split(":"); diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java index cbfc46703..77778d885 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new FifotrackProtocolDecoder(null)); + verifyAttributes(decoder, buffer( + "$$159,866344056951341,399D,A03,,230716222659,240|8|2724|20EEF33,4.20,100,003E,1,AE233FC0D2E0:-65|3E286D5FB6E8:-65|28BD890A4A0E:-67|8ED81B5DFC3A:-70|8AD81B5DFC3A:-70*5F")); + verifyAttribute(decoder, buffer( "$$99,865413050150407,7F,A03,,230626072722,460|0|25FC|AC2AB0B,3.74,52,0019,0,A,0,13,22.643466,114.018211*74"), Position.KEY_SATELLITES, 13); -- cgit v1.2.3 From fc3c3ee38bdfd51ed1f56488661becffecceb3ef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 23 Jul 2023 07:22:20 -0700 Subject: Device inactivity group config --- .../schedule/TaskDeviceInactivityCheck.java | 37 ++++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index 57c64dc5b..81567ec31 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.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. @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory; import org.traccar.database.NotificationManager; import org.traccar.model.Device; import org.traccar.model.Event; +import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -31,6 +32,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; public class TaskDeviceInactivityCheck implements ScheduleTask { @@ -64,22 +66,45 @@ public class TaskDeviceInactivityCheck implements ScheduleTask { Map events = new HashMap<>(); try { + Map groups = storage.getObjects(Group.class, new Request(new Columns.All())) + .stream().collect(Collectors.toMap(Group::getId, group -> group)); for (Device device : storage.getObjects(Device.class, new Request(new Columns.All()))) { - if (device.getLastUpdate() != null && checkDevice(device, currentTime, checkPeriod)) { + if (device.getLastUpdate() != null && checkDevice(device, groups, currentTime, checkPeriod)) { Event event = new Event(Event.TYPE_DEVICE_INACTIVE, device.getId()); event.set(ATTRIBUTE_LAST_UPDATE, device.getLastUpdate().getTime()); events.put(event, null); } } } catch (StorageException e) { - LOGGER.warn("Get devices error", e); + LOGGER.warn("Database error", e); } notificationManager.updateEvents(events); } - private boolean checkDevice(Device device, long currentTime, long checkPeriod) { - long deviceInactivityStart = device.getLong(ATTRIBUTE_DEVICE_INACTIVITY_START); + private long getAttribute(Device device, Map groups, String key) { + long deviceValue = device.getLong(key); + if (deviceValue > 0) { + return deviceValue; + } else { + long groupId = device.getGroupId(); + while (groupId > 0) { + Group group = groups.get(groupId); + if (group == null) { + return 0; + } + long groupValue = group.getLong(key); + if (groupValue > 0) { + return groupValue; + } + groupId = group.getGroupId(); + } + return 0; + } + } + + private boolean checkDevice(Device device, Map groups, long currentTime, long checkPeriod) { + long deviceInactivityStart = getAttribute(device, groups, ATTRIBUTE_DEVICE_INACTIVITY_START); if (deviceInactivityStart > 0) { long timeThreshold = device.getLastUpdate().getTime() + deviceInactivityStart; if (currentTime >= timeThreshold) { @@ -88,7 +113,7 @@ public class TaskDeviceInactivityCheck implements ScheduleTask { return true; } - long deviceInactivityPeriod = device.getLong(ATTRIBUTE_DEVICE_INACTIVITY_PERIOD); + long deviceInactivityPeriod = getAttribute(device, groups, ATTRIBUTE_DEVICE_INACTIVITY_PERIOD); if (deviceInactivityPeriod > 0) { long count = (currentTime - timeThreshold - 1) / deviceInactivityPeriod; timeThreshold += count * deviceInactivityPeriod; -- cgit v1.2.3 From 6e5481ebb1858726604706d011e5c5f509ac5306 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 24 Jul 2023 07:26:18 -0700 Subject: Fix VL03 ignition decoding --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index f7cdd3920..d6d988423 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -345,7 +345,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { mnc = buf.readUnsignedByte(); } int lac; - if (type == MSG_LBS_ALARM) { + if (type == MSG_LBS_ALARM || type == MSG_GPS_LBS_7) { lac = buf.readInt(); } else { lac = buf.readUnsignedShort(); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index cc71eb9bd..68579e815 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "787829a01707150f2d0ecd01635100041e96d000087c02d4020000912e000000000718798d000e0006ed3ce50d0a"), + Position.KEY_IGNITION, false); + verifyNotNull(decoder, binary( "787829a0170704112226cf0163fe7c0420f6f000091302d402000091290000000007186b8f01030001460d010d0a")); -- cgit v1.2.3 From 6cb4db1f6bb4f93ad42b013a38ace9a6a3b735f6 Mon Sep 17 00:00:00 2001 From: seym45 Date: Mon, 24 Jul 2023 01:25:05 +0400 Subject: Define command 'rollback' --- src/main/java/org/traccar/model/Command.java | 1 + .../java/org/traccar/protocol/GatorProtocol.java | 5 +++ .../org/traccar/protocol/GatorProtocolEncoder.java | 52 ++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/GatorProtocolEncoder.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 99988dd82..e0c1c3976 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -45,6 +45,7 @@ public class Command extends BaseCommand { public static final String TYPE_SILENCE_TIME = "silenceTime"; public static final String TYPE_SET_PHONEBOOK = "setPhonebook"; public static final String TYPE_MESSAGE = "message"; + public static final String TYPE_ROLLCALL = "rollcall"; public static final String TYPE_VOICE_MESSAGE = "voiceMessage"; public static final String TYPE_OUTPUT_CONTROL = "outputControl"; public static final String TYPE_VOICE_MONITORING = "voiceMonitoring"; diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index 7341b69a3..c54b1b53d 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -20,6 +20,7 @@ import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import org.traccar.model.Command; import javax.inject.Inject; @@ -27,10 +28,14 @@ public class GatorProtocol extends BaseProtocol { @Inject public GatorProtocol(Config config) { + setSupportedDataCommands( + Command.TYPE_ROLLCALL + ); addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); + pipeline.addLast(new GatorProtocolEncoder(GatorProtocol.this)); pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java new file mode 100644 index 000000000..452fde275 --- /dev/null +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -0,0 +1,52 @@ +/* + * Copyright 2023 - Hossain Mohammad Seym + * + * 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 org.traccar.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.config.Keys; +import org.traccar.helper.Checksum; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.model.Command; +import org.traccar.model.Device; + +import java.nio.charset.StandardCharsets; + +public class GatorProtocolEncoder extends BaseProtocolEncoder { + + public GatorProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private ByteBuf encodeContent(long deviceId, String content) { + // FIXME: implement this method + return null; + } + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_ROLLCALL: + return encodeContent(command.getDeviceId(), "0x30"); + default: + return null; + } + } + +} -- cgit v1.2.3 From 1ee9e9396d7274f057f5e6d2d69e72ec1a5c0135 Mon Sep 17 00:00:00 2001 From: seym45 Date: Mon, 24 Jul 2023 20:15:47 +0400 Subject: Add method to encodeId --- .../org/traccar/protocol/GatorProtocolEncoder.java | 36 ++++++++++++++++++++-- .../traccar/protocol/GatorProtocolEncoderTest.java | 19 ++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index 452fde275..df85a712c 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.Checksum; +import org.traccar.helper.DataConverter; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import org.traccar.model.Device; @@ -33,9 +34,38 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { super(protocol); } - private ByteBuf encodeContent(long deviceId, String content) { + + public static String encodeId(long deviceId) { + StringBuilder encodedId = new StringBuilder(); + + String imei = String.valueOf(deviceId); + String a = imei.substring(1, 3); + String b = imei.substring(3, 5); + String c = imei.substring(5, 7); + String d = imei.substring(7, 9); + String e = imei.substring(9); + String[] arr = {b, c, d, e}; + + String binaryFirstDigit = Integer.toBinaryString(Integer.valueOf(a) - 30); + binaryFirstDigit = String.format("%4s", binaryFirstDigit).replace(' ', '0'); + + for (int i = 0; i < 4; i++) { + int sum = Integer.parseInt(arr[i]) + Integer.parseInt(String.valueOf(binaryFirstDigit.charAt(i)) + "0000000", 2); + arr[i] = Integer.toHexString(sum).toUpperCase(); + arr[i] = String.format("%2s", arr[i]).replace(' ', '0'); + } + + for (String s : arr) { + encodedId.append(s); + } + + return encodedId.toString(); + } + + + private ByteBuf encodeContent(long deviceId, String mainOrder, String content) { // FIXME: implement this method - return null; + return null; } @Override @@ -43,7 +73,7 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { switch (command.getType()) { case Command.TYPE_ROLLCALL: - return encodeContent(command.getDeviceId(), "0x30"); + return encodeContent(command.getDeviceId(), "30", null); default: return null; } diff --git a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java new file mode 100644 index 000000000..7e8f51008 --- /dev/null +++ b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import org.junit.jupiter.api.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class GatorProtocolEncoderTest extends ProtocolTest { + + @Test + void encodeId() throws Exception { + var encoder = inject(new GatorProtocolEncoder(null)); + assertEquals("2008958C", encoder.encodeId(13332082112L)); + + } +} -- cgit v1.2.3 From 09daf15be1a874a8880645d4595e1b57d4cf2eee Mon Sep 17 00:00:00 2001 From: seym45 Date: Mon, 24 Jul 2023 20:29:29 +0400 Subject: Add method to get calibration byte --- src/main/java/org/traccar/protocol/GatorProtocolEncoder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index df85a712c..0d4353c8f 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -62,12 +62,24 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { return encodedId.toString(); } + private static String getCalibrationByteFromHexString(String data) { + String response = ""; + int calib = 0; + int length = data.length() / 2; + for (int i = 0; i < length; i++) { + calib = calib ^ Integer.parseInt(data.substring(i * 2, i * 2 + 2), 16); + } + response = Integer.toHexString(calib).toUpperCase(); + response = String.format("%2s", response).replace(' ', '0'); + return response; + } private ByteBuf encodeContent(long deviceId, String mainOrder, String content) { // FIXME: implement this method return null; } + @Override protected Object encodeCommand(Command command) { -- cgit v1.2.3 From 103fbde721753b8be65c39e0e9118943c6bebc68 Mon Sep 17 00:00:00 2001 From: seym45 Date: Mon, 24 Jul 2023 20:34:00 +0400 Subject: Add Gator content encoder and test snippets --- src/main/java/org/traccar/protocol/GatorProtocolEncoder.java | 10 ++++++++-- .../java/org/traccar/protocol/GatorProtocolEncoderTest.java | 12 +++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index 0d4353c8f..125031eee 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -75,8 +75,14 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { } private ByteBuf encodeContent(long deviceId, String mainOrder, String content) { - // FIXME: implement this method - return null; + String pseudoIPAddress = encodeId(deviceId); + int length = 4 + 1 + 1; // ip 4 bytes, calibration byte and end byte + String hexStringLength = String.format("%02X", length); + + String packet = "2424" + mainOrder + "00" + hexStringLength + pseudoIPAddress; + String calibration = getCalibrationByteFromHexString(packet); + packet = packet + calibration + "0D"; + return Unpooled.wrappedBuffer(DataConverter.parseHex(packet)); } diff --git a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java index 7e8f51008..74ac35440 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java @@ -4,16 +4,22 @@ import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; -import java.nio.charset.StandardCharsets; - import static org.junit.jupiter.api.Assertions.assertEquals; public class GatorProtocolEncoderTest extends ProtocolTest { @Test - void encodeId() throws Exception { + void encodeId() throws Exception { var encoder = inject(new GatorProtocolEncoder(null)); assertEquals("2008958C", encoder.encodeId(13332082112L)); + } + @Test + public void testEncode() throws Exception { + var encoder = inject(new GatorProtocolEncoder(null)); + Command command = new Command(); + command.setDeviceId(13332082112L); + command.setType(Command.TYPE_ROLLCALL); + verifyCommand(encoder, command, binary("24243000062008958C070D")); } } -- cgit v1.2.3 From 8c227973608eee7ba5519f22c5781f912dd4e9b5 Mon Sep 17 00:00:00 2001 From: seym45 Date: Tue, 25 Jul 2023 10:56:55 +0400 Subject: Change command type --- src/main/java/org/traccar/model/Command.java | 1 - src/main/java/org/traccar/protocol/GatorProtocol.java | 2 +- src/main/java/org/traccar/protocol/GatorProtocolEncoder.java | 4 ++-- src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index e0c1c3976..99988dd82 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -45,7 +45,6 @@ public class Command extends BaseCommand { public static final String TYPE_SILENCE_TIME = "silenceTime"; public static final String TYPE_SET_PHONEBOOK = "setPhonebook"; public static final String TYPE_MESSAGE = "message"; - public static final String TYPE_ROLLCALL = "rollcall"; public static final String TYPE_VOICE_MESSAGE = "voiceMessage"; public static final String TYPE_OUTPUT_CONTROL = "outputControl"; public static final String TYPE_VOICE_MONITORING = "voiceMonitoring"; diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index c54b1b53d..bb0e017f4 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -29,7 +29,7 @@ public class GatorProtocol extends BaseProtocol { @Inject public GatorProtocol(Config config) { setSupportedDataCommands( - Command.TYPE_ROLLCALL + Command.TYPE_POSITION_SINGLE ); addServer(new TrackerServer(config, getName(), false) { @Override diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index 125031eee..efe8715e3 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -90,11 +90,11 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { protected Object encodeCommand(Command command) { switch (command.getType()) { - case Command.TYPE_ROLLCALL: + // According to Protocol Documentation, 0x30 is for rollcall command + case Command.TYPE_POSITION_SINGLE: return encodeContent(command.getDeviceId(), "30", null); default: return null; } } - } diff --git a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java index 74ac35440..04fce0ac8 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java @@ -19,7 +19,7 @@ public class GatorProtocolEncoderTest extends ProtocolTest { var encoder = inject(new GatorProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(13332082112L); - command.setType(Command.TYPE_ROLLCALL); + command.setType(Command.TYPE_POSITION_SINGLE); verifyCommand(encoder, command, binary("24243000062008958C070D")); } } -- cgit v1.2.3 From 1a1126d2d39220f3f28d98662a8c3d5fd4c1cfee Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 25 Jul 2023 05:15:13 -0700 Subject: Handle ST410 no GPS data --- .../traccar/protocol/SuntechProtocolDecoder.java | 26 ++++++++++++++-------- .../protocol/SuntechProtocolDecoderTest.java | 3 +++ 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 047a1822a..86a8bf6fe 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -271,18 +271,26 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { index += 1; // collaborative network } - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - position.setTime(dateFormat.parse(values[index++] + values[index++])); + if (values[index].isEmpty()) { - position.setLatitude(Double.parseDouble(values[index++])); - position.setLongitude(Double.parseDouble(values[index++])); - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - position.setCourse(Double.parseDouble(values[index++])); + getLastLocation(position, null); - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + } else { - position.setValid(values[index++].equals("1")); + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setTime(dateFormat.parse(values[index++] + values[index++])); + + position.setLatitude(Double.parseDouble(values[index++])); + position.setLongitude(Double.parseDouble(values[index++])); + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + position.setCourse(Double.parseDouble(values[index++])); + + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + + position.setValid(values[index++].equals("1")); + + } return position; } diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 884f13350..cbb68132f 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { var decoder = inject(new SuntechProtocolDecoder(null)); + verifyAttributes(decoder, buffer( + "ST410STT;109815653;445;03;16531;724;10;-77;6011;7;16273;724;10;7511;0;0;13903;724;10;6011;0;0;7671;724;10;7111;0;0;16533;724;10;6011;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3.86;0;0098;1;003;;;;;;;;;")); + verifyPosition(decoder, buffer( "ALT;0840037569;FFFFFF;84;1.0.6;0;20221228;11:33:05;00004490;724;11;05D3;33;-22.845935;-46.322000;0.00;0.00;18;0;00000001;00000000;99;;;;08E3800F;4.1;12.37;0;0;0;0;4;;;;")); -- cgit v1.2.3 From 413d9a49c41a27a221f2350e5cd4864c1231bb50 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 25 Jul 2023 05:41:16 -0700 Subject: Decode HS-5000G odometer value --- src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java | 9 ++++++--- .../java/org/traccar/protocol/HuaShengProtocolDecoderTest.java | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 1ad27be5f..7d634b0f2 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -229,7 +229,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { position.setCourse(buf.readUnsignedShort()); position.setAltitude(buf.readUnsignedShort()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000); + buf.readUnsignedShort(); // odometer speed Network network = new Network(); @@ -264,8 +264,11 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // run time break; case 0x0009: - position.set( - Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); + position.set(Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); + break; + case 0x0010: + position.set(Position.KEY_ODOMETER, Double.parseDouble( + buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()) * 1000); break; case 0x0011: position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 0.05); diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java index a54fa53c6..d8cc739ab 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java @@ -20,6 +20,10 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "c000000077aa0200000000000e000100143347315f48312e315f56312e30372e54000300133335353835353035303434303635380004000b3531323030303000050005010006000400070004000800050000090018383936313032353431343533333239313833360d000a000f796573696e7465726e6574c0")); + verifyAttribute(decoder, binary( + "c0000000bdaa0000000000061d480000083233303132333039323634330000000000000000000000a600140000000100187e02de0a00290372000005951600260000004a0000040009080000004a0005000a0d0000000ad0000900154d414b474d363639484a4e333031383739000f00133836323230353035353338393836320010001031333231322e30303030303000110008000000000014000bf851084f000018001500060000002000153430344030354035363532403130363332c0"), + Position.KEY_ODOMETER, 13212000.0); + verifyNotNull(decoder, binary( "c0000000b9aa00000000000013c800001132333035303431343537323600186bc30045e5b8002a008b0077002d000100187f0c4b2600d906ec000005938800000000000e0000040009110000000e0005000a1d0400000079000900154646464646464646464646464646464646000f00133836323230353035353339313733360010000c302e30303030303000110008000000000014000bf81b204901b52a001500060000002000153231394030324030403130343438393139c0")); -- cgit v1.2.3 From 6ac15f2c6fb8798c6906c24e97b0048736270215 Mon Sep 17 00:00:00 2001 From: seym45 Date: Wed, 26 Jul 2023 03:02:34 +0400 Subject: Format code structure --- src/main/java/org/traccar/protocol/GatorProtocol.java | 4 +--- src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index bb0e017f4..46862f583 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -28,9 +28,7 @@ public class GatorProtocol extends BaseProtocol { @Inject public GatorProtocol(Config config) { - setSupportedDataCommands( - Command.TYPE_POSITION_SINGLE - ); + setSupportedDataCommands(Command.TYPE_POSITION_SINGLE); addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { diff --git a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java index 04fce0ac8..a3bc3af2b 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java @@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class GatorProtocolEncoderTest extends ProtocolTest { @Test - void encodeId() throws Exception { + void testEncodeId() throws Exception { var encoder = inject(new GatorProtocolEncoder(null)); assertEquals("2008958C", encoder.encodeId(13332082112L)); } -- cgit v1.2.3 From 2407799dc370d741431cbec056c0f2acbe454bf3 Mon Sep 17 00:00:00 2001 From: seym45 Date: Wed, 26 Jul 2023 04:11:40 +0400 Subject: Refactor method encodeId and encodeContent - Replace method getCalibrationByteFromHexString with xor checksum - Rewrite method encodeContent with ByteBuf instead of String - Refactor encodeId by replacing short variable names and use ByteBuf --- .../org/traccar/protocol/GatorProtocolEncoder.java | 83 ++++++++++------------ .../traccar/protocol/GatorProtocolEncoderTest.java | 9 ++- 2 files changed, 44 insertions(+), 48 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index efe8715e3..296ff4f13 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 - Hossain Mohammad Seym + * Copyright 2023 Hossain Mohammad Seym (seym45@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,11 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; -import org.traccar.config.Keys; import org.traccar.helper.Checksum; -import org.traccar.helper.DataConverter; -import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import org.traccar.model.Device; -import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; public class GatorProtocolEncoder extends BaseProtocolEncoder { @@ -34,65 +31,57 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { super(protocol); } + public static ByteBuf encodeId(long deviceId) { + ByteBuf buf = Unpooled.buffer(); - public static String encodeId(long deviceId) { - StringBuilder encodedId = new StringBuilder(); - - String imei = String.valueOf(deviceId); - String a = imei.substring(1, 3); - String b = imei.substring(3, 5); - String c = imei.substring(5, 7); - String d = imei.substring(7, 9); - String e = imei.substring(9); - String[] arr = {b, c, d, e}; + String deviceIdStrVal = String.valueOf(deviceId); + List partialDigits = new ArrayList<>(); + for (int i = 1; i < deviceIdStrVal.length(); i += 2) { + partialDigits.add(deviceIdStrVal.substring(i, i + 2)); + } - String binaryFirstDigit = Integer.toBinaryString(Integer.valueOf(a) - 30); - binaryFirstDigit = String.format("%4s", binaryFirstDigit).replace(' ', '0'); + int firstDigit = Integer.parseInt(partialDigits.get(0)) - 30; - for (int i = 0; i < 4; i++) { - int sum = Integer.parseInt(arr[i]) + Integer.parseInt(String.valueOf(binaryFirstDigit.charAt(i)) + "0000000", 2); - arr[i] = Integer.toHexString(sum).toUpperCase(); - arr[i] = String.format("%2s", arr[i]).replace(' ', '0'); - } + for (int i = 1; i < partialDigits.size(); i++) { + int shiftCount = 4 - i; + int addend = ((firstDigit & (1 << shiftCount)) >> shiftCount) << 7; + int sum = Integer.parseInt(partialDigits.get(i)) | addend; - for (String s : arr) { - encodedId.append(s); + buf.writeByte(sum); } - return encodedId.toString(); + return buf; } - private static String getCalibrationByteFromHexString(String data) { - String response = ""; - int calib = 0; - int length = data.length() / 2; - for (int i = 0; i < length; i++) { - calib = calib ^ Integer.parseInt(data.substring(i * 2, i * 2 + 2), 16); - } - response = Integer.toHexString(calib).toUpperCase(); - response = String.format("%2s", response).replace(' ', '0'); - return response; - } - private ByteBuf encodeContent(long deviceId, String mainOrder, String content) { - String pseudoIPAddress = encodeId(deviceId); + private ByteBuf encodeContent(long deviceId, int mainOrder) { + ByteBuf buf = Unpooled.buffer(); + + buf.writeByte(0x24); + buf.writeByte(0x24); + buf.writeByte(mainOrder); + buf.writeByte(0x00); + int length = 4 + 1 + 1; // ip 4 bytes, calibration byte and end byte - String hexStringLength = String.format("%02X", length); + buf.writeByte(length); - String packet = "2424" + mainOrder + "00" + hexStringLength + pseudoIPAddress; - String calibration = getCalibrationByteFromHexString(packet); - packet = packet + calibration + "0D"; - return Unpooled.wrappedBuffer(DataConverter.parseHex(packet)); - } + ByteBuf pseudoIPAddress = encodeId(deviceId); + buf.writeBytes(pseudoIPAddress); + + int checksum = Checksum.xor(buf.nioBuffer()); + buf.writeByte(checksum); + buf.writeByte(0x0D); + + return buf; + } @Override protected Object encodeCommand(Command command) { switch (command.getType()) { - // According to Protocol Documentation, 0x30 is for rollcall command case Command.TYPE_POSITION_SINGLE: - return encodeContent(command.getDeviceId(), "30", null); + return encodeContent(command.getDeviceId(), 0x30); default: return null; } diff --git a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java index a3bc3af2b..babd7285d 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java @@ -1,5 +1,7 @@ package org.traccar.protocol; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; @@ -11,7 +13,12 @@ public class GatorProtocolEncoderTest extends ProtocolTest { @Test void testEncodeId() throws Exception { var encoder = inject(new GatorProtocolEncoder(null)); - assertEquals("2008958C", encoder.encodeId(13332082112L)); + ByteBuf pseudoId = Unpooled.buffer(); + pseudoId.writeByte(0x20); + pseudoId.writeByte(0x08); + pseudoId.writeByte(0x95); + pseudoId.writeByte(0x8C); + assertEquals(pseudoId, encoder.encodeId(13332082112L)); } @Test -- cgit v1.2.3 From 9b680956acccb5bd64b6c9c6eee1428e93387719 Mon Sep 17 00:00:00 2001 From: seym45 Date: Wed, 26 Jul 2023 04:21:23 +0400 Subject: Remove extra line --- src/main/java/org/traccar/protocol/GatorProtocolEncoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index 296ff4f13..c4f06dbc5 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -53,7 +53,6 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { return buf; } - private ByteBuf encodeContent(long deviceId, int mainOrder) { ByteBuf buf = Unpooled.buffer(); -- cgit v1.2.3 From 18c1e761fd203c994445ac85e808ca6f672d0ec5 Mon Sep 17 00:00:00 2001 From: seym45 Date: Wed, 26 Jul 2023 11:11:15 +0400 Subject: Resolve suggestions - Define MSG_POSITION_REQUEST - Change comment "calibration" to "checksum" --- src/main/java/org/traccar/protocol/GatorProtocolDecoder.java | 1 + src/main/java/org/traccar/protocol/GatorProtocolEncoder.java | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java index 644caee81..f7da5dc75 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java @@ -37,6 +37,7 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder { } public static final int MSG_HEARTBEAT = 0x21; + public static final int MSG_POSITION_REQUEST = 0x30; public static final int MSG_POSITION_DATA = 0x80; public static final int MSG_ROLLCALL_RESPONSE = 0x81; public static final int MSG_ALARM_DATA = 0x82; diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index c4f06dbc5..f2c522067 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -60,9 +60,7 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { buf.writeByte(0x24); buf.writeByte(mainOrder); buf.writeByte(0x00); - - int length = 4 + 1 + 1; // ip 4 bytes, calibration byte and end byte - buf.writeByte(length); + buf.writeByte(4 + 1 + 1); // ip 4 bytes, checksum and end byte ByteBuf pseudoIPAddress = encodeId(deviceId); buf.writeBytes(pseudoIPAddress); @@ -80,7 +78,7 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { switch (command.getType()) { case Command.TYPE_POSITION_SINGLE: - return encodeContent(command.getDeviceId(), 0x30); + return encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_POSITION_REQUEST); default: return null; } -- cgit v1.2.3 From fb4db390187fbfcf1220dc05fa03565799a829e8 Mon Sep 17 00:00:00 2001 From: seym45 Date: Thu, 27 Jul 2023 02:19:03 +0400 Subject: Simplify encodeId method for Gator Protocol --- .../org/traccar/protocol/GatorProtocolEncoder.java | 28 +++++++--------------- .../traccar/protocol/GatorProtocolEncoderTest.java | 12 ++++++++-- 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index f2c522067..3d38b7455 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -22,43 +22,33 @@ import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import java.util.ArrayList; -import java.util.List; - public class GatorProtocolEncoder extends BaseProtocolEncoder { public GatorProtocolEncoder(Protocol protocol) { super(protocol); } - public static ByteBuf encodeId(long deviceId) { + public ByteBuf encodeId(long deviceId) { ByteBuf buf = Unpooled.buffer(); - String deviceIdStrVal = String.valueOf(deviceId); - List partialDigits = new ArrayList<>(); - for (int i = 1; i < deviceIdStrVal.length(); i += 2) { - partialDigits.add(deviceIdStrVal.substring(i, i + 2)); - } - - int firstDigit = Integer.parseInt(partialDigits.get(0)) - 30; + String id = getUniqueId(deviceId); - for (int i = 1; i < partialDigits.size(); i++) { - int shiftCount = 4 - i; - int addend = ((firstDigit & (1 << shiftCount)) >> shiftCount) << 7; - int sum = Integer.parseInt(partialDigits.get(i)) | addend; + int firstDigit = Integer.parseInt(id.substring(1, 3)) - 30; - buf.writeByte(sum); - } + buf.writeByte(Integer.parseInt(id.substring(3, 5)) | (((firstDigit >> 3) & 1) << 7)); + buf.writeByte(Integer.parseInt(id.substring(5, 7)) | (((firstDigit >> 2) & 1) << 7)); + buf.writeByte(Integer.parseInt(id.substring(7, 9)) | (((firstDigit >> 1) & 1) << 7)); + buf.writeByte(Integer.parseInt(id.substring(9)) | ((firstDigit & 1) << 7)); return buf; } - private ByteBuf encodeContent(long deviceId, int mainOrder) { + private ByteBuf encodeContent(long deviceId, int type) { ByteBuf buf = Unpooled.buffer(); buf.writeByte(0x24); buf.writeByte(0x24); - buf.writeByte(mainOrder); + buf.writeByte(type); buf.writeByte(0x00); buf.writeByte(4 + 1 + 1); // ip 4 bytes, checksum and end byte diff --git a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java index babd7285d..3f8fe2451 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolEncoderTest.java @@ -5,27 +5,35 @@ import io.netty.buffer.Unpooled; import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; +import org.traccar.model.Device; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; public class GatorProtocolEncoderTest extends ProtocolTest { @Test void testEncodeId() throws Exception { var encoder = inject(new GatorProtocolEncoder(null)); + var device = encoder.getCacheManager().getObject(Device.class, 1); + when(device.getUniqueId()).thenReturn("13332082112"); + ByteBuf pseudoId = Unpooled.buffer(); pseudoId.writeByte(0x20); pseudoId.writeByte(0x08); pseudoId.writeByte(0x95); pseudoId.writeByte(0x8C); - assertEquals(pseudoId, encoder.encodeId(13332082112L)); + assertEquals(pseudoId, encoder.encodeId(1)); } @Test public void testEncode() throws Exception { var encoder = inject(new GatorProtocolEncoder(null)); + var device = encoder.getCacheManager().getObject(Device.class, 1); + when(device.getUniqueId()).thenReturn("13332082112"); + Command command = new Command(); - command.setDeviceId(13332082112L); + command.setDeviceId(1); command.setType(Command.TYPE_POSITION_SINGLE); verifyCommand(encoder, command, binary("24243000062008958C070D")); } -- cgit v1.2.3 From d4db066c6e0295a4c8646d82a982cd82e42c84c4 Mon Sep 17 00:00:00 2001 From: Mohamed Khalil HADDED Date: Sat, 29 Jul 2023 00:55:09 +0100 Subject: Watch Protocol Decoder update --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 7 +++++-- src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 40d56b130..b586f4e92 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -51,7 +51,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { .number("(dd)(dd)(dd),") // time (hhmmss) .expression("([AV]),") // validity .number(" *(-?d+.d+),") // latitude - .expression("([NS]),") + .expression("([NS])?,") .number(" *(-?d+.d+),") // longitude .expression("([EW])?,") .number("(d+.?d*),") // speed @@ -285,7 +285,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { || type.equalsIgnoreCase("BLOOD") || type.equalsIgnoreCase("BPHRT") || type.equalsIgnoreCase("TEMP") - || type.equalsIgnoreCase("btemp2")) { + || type.equalsIgnoreCase("btemp2") + || type.equalsIgnoreCase("oxygen")) { if (buf.isReadable()) { @@ -303,6 +304,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { if (Integer.parseInt(values[valueIndex++]) > 0) { position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(values[valueIndex])); } + } else if (type.equalsIgnoreCase("oxygen")) { + position.set("bloodOxygen", Integer.parseInt(values[++valueIndex])); } else { if (type.equalsIgnoreCase("BPHRT") || type.equalsIgnoreCase("BLOOD")) { position.set("pressureHigh", values[valueIndex++]); diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 855b9792c..5fd0ede44 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -17,6 +17,13 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = inject(new WatchProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "[3G*9705141740*000B*oxygen,0,98]"), + "bloodOxygen", 98); + + verifyPosition(decoder, buffer( + "[3G*9705141740*00C2*UD_LTE,260723,185105,V,00.000000,,00.0000000,,0.00,0.0,0.0,0,100,67,0,0,00000000,2,0,605,1,10006,65799,14,10020,4104,4,3,,34:60:f9:ec:19:f8,-82,,98:48:27:55:18:20,-96,,34:e8:94:e4:06:18,-104,0.0]")); + verifyPosition(decoder, buffer( "[SG*9059011020*0067*AL,240123,181628,V,54.427538,N,6.409275,W,0.00,0,0,0,19,90,0,0,00000000,1,1,234,10,55C0,3B882A2,132,,10]")); -- cgit v1.2.3 From 230f629c3dce039aa8856fe2fb4c447a086d72e4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Aug 2023 21:06:41 -0700 Subject: Handle invalid Ruptela GPS (fix #5152) --- .../traccar/protocol/RuptelaProtocolDecoder.java | 26 +++++++++++++--------- .../protocol/RuptelaProtocolDecoderTest.java | 3 +++ 2 files changed, 18 insertions(+), 11 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 2122d5081..649de7c5c 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -248,17 +248,21 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // priority (reserved) - position.setValid(true); - position.setLongitude(buf.readInt() / 10000000.0); - position.setLatitude(buf.readInt() / 10000000.0); - position.setAltitude(buf.readUnsignedShort() / 10.0); - position.setCourse(buf.readUnsignedShort() / 100.0); - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - - position.set(Position.KEY_HDOP, buf.readUnsignedByte() / 10.0); + int longitude = buf.readInt(); + int latitude = buf.readInt(); + if (longitude > Integer.MIN_VALUE && latitude > Integer.MIN_VALUE) { + position.setValid(true); + position.setLongitude(longitude / 10000000.0); + position.setLatitude(latitude / 10000000.0); + position.setAltitude(buf.readUnsignedShort() / 10.0); + position.setCourse(buf.readUnsignedShort() / 100.0); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); + position.set(Position.KEY_HDOP, buf.readUnsignedByte() / 10.0); + } else { + buf.skipBytes(8); + getLastLocation(position, null); + } if (type == MSG_EXTENDED_RECORDS) { position.set(Position.KEY_EVENT, buf.readUnsignedShort()); diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java index f214ce5f8..e98dffdef 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class RuptelaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "002e000316d53d58d6020f4573303430302e30332e36382e30340000c2b3090d0e950000827b000003e80000003c003c1681")); + verifyPositions(decoder, false, binary( + "03fb0003137ca79f856d01011d386d438b000080000000800000008000ffffffffffff070220211bff011d30c50000386d438b000080000000800000008000ffffffffffff0702201f1bff011d30c30000386d43a9000180000000800000008000ffffffffffffad0320211b16ad01011d30950000386d43c7000080000000800000008000ffffffffffff070220211b00011d30a60000386d4403000080000000800000008000ffffffffffff070220221b00011d30ae0000386d443f000080000000800000008000ffffffffffff070220231b00011d30ae000064c692cb000080000000800000008000ffffffffffff070220231b18011d3091000064c69306000080000000800000008000ffffffffffff070220231b14011d30a7000064c69322000180000000800000008000ffffffffffffad0320241b14ad00011d30a3000064c69342000080000000800000008000ffffffffffff070220241b13011d30ad000064c6934a000180000000800000008000ffffffffffffad0320241b10ad01011d30c3000064c6937e000080000000800000008000ffffffffffff070220241b12011d3092000064c6938b000180000000800000008000ffffffffffffad0320241b12ad00011d30bd000064c69395000180000000800000008000ffffffffffffad0320241b10ad01011d30a6000064c693ba000080000000800000008000ffffffffffff070220251b17011d30a2000064c693d4000180000000800000008000ffffffffffffad0320251b17ad00011d30cc000064c693f6000080000000800000008000ffffffffffff070220251b15011d3090000064c69404000180000000800000008000ffffffffffffad0320251b16ad01011d30a9000064c69432000080000000800000008000ffffffffffff070220261b14011d30be000064c6946d000180000000800000008000ffffffffffffad0320261b15ad00011d30b1000064c6946e000080000000800000008000ffffffffffff070220261b15011d3096000064c694aa000080000000800000008000ffffffffffff070220261b15011d30a8000064c694b2000180000000800000008000ffffffffffffad0320261b15ad01011d30a5000064c694e6000080000000800000008000ffffffffffff070220261b17011d309a000064c694f5000180000000800000008000ffffffffffffad0320261b17ad00011d309c000064c694f6000180000000800000008000ffffffffffffad0320261b17ad01011d3099000064c69522000080000000800000008000ffffffffffff070220261b14011d3094000064c6955e000080000000800000008000ffffffffffff070220261b15011d30b2000064c6959a000080000000800000008000ffffffffffff070220261b14011d30970000ad9e")); + verifyPositions(decoder, binary( "00800003167d765c155d01000160cd0a310000faae43f7176ee45702332b0c12000006070d05007300cfff260082008600870088000f00d7021100d801c900061d0000c500001e0e988300008900008b000002d0000c9bca720c889a0b047e00000000000000007f0000000000000000800000000000000000810000000000000000a341")); -- cgit v1.2.3 From 95fdfd770130b774e6201ddc88bba9241c95e3cc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Aug 2023 21:17:52 -0700 Subject: Fix GT06 protocol conflict --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 7 ------- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index d6d988423..4762fc884 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -836,11 +836,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - if (type == MSG_STATUS && variant == Variant.VXT01) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - } - if (type == MSG_GPS_LBS_1) { if (variant == Variant.GT06E_CARD) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); @@ -1421,8 +1416,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_1 && length == 0x24) { variant = Variant.VXT01; - } else if (header == 0x7878 && type == MSG_STATUS && length == 0x0a) { - variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x31) { variant = Variant.WANWAY_S20; } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x2e) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 68579e815..40f268a9d 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -34,7 +34,7 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyAttribute(decoder, binary( "78780a130604ea04000006bc8a0d0a"), - Position.KEY_POWER, 0.0); + Position.KEY_POWER, null); verifyAttributes(decoder, binary( "797900849404414c4d313d43353b414c4d323d43433b414c4d333d35433b535441313d43303b4459443d30313b534f533d303133323838333730302c2c3b43454e5445523d303133323838333730303b46454e43453d46656e63652c4f46462c302c302e3030303030302c302e3030303030302c3330302c494e206f72204f55542c313b00b79d120d0a")); -- cgit v1.2.3 From d979ab718ff043c6ec6b815e9833621b9fe0e566 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Aug 2023 17:12:49 -0700 Subject: Support JC400 alarm messages --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 37 ++++++++++++++++++---- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 4 +++ 2 files changed, 34 insertions(+), 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 4762fc884..53c812bb7 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -121,6 +121,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { STANDARD, OBD6, WETRUST, + JC400, } private Variant variant; @@ -269,12 +270,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } public static boolean decodeGps(Position position, ByteBuf buf, boolean hasLength, TimeZone timezone) { - return decodeGps(position, buf, hasLength, true, true, timezone); + return decodeGps(position, buf, hasLength, true, true, false, timezone); } public static boolean decodeGps( Position position, ByteBuf buf, boolean hasLength, boolean hasSatellites, - boolean hasSpeed, TimeZone timezone) { + boolean hasSpeed, boolean longSpeed, TimeZone timezone) { DateBuilder dateBuilder = new DateBuilder(timezone) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -293,7 +294,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; if (hasSpeed) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + position.setSpeed(UnitsConverter.knotsFromKph( + longSpeed ? buf.readUnsignedShort() : buf.readUnsignedByte())); } int flags = buf.readUnsignedShort(); @@ -928,24 +930,44 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { boolean extendedAlarm = dataLength > 7; if (extendedAlarm) { - decodeGps(position, buf, false, false, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); + if (variant == Variant.JC400) { + buf.readUnsignedShort(); // marker + buf.readUnsignedByte(); // version + } + decodeGps( + position, buf, false, + variant == Variant.JC400, variant == Variant.JC400, variant == Variant.JC400, + deviceSession.get(DeviceSession.KEY_TIMEZONE)); } else { DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); getLastLocation(position, dateBuilder.getDate()); } - short alarmType = buf.readUnsignedByte(); - switch (alarmType) { + if (variant == Variant.JC400) { + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); + } + short event = buf.readUnsignedByte(); + position.set(Position.KEY_EVENT, event); + switch (event) { case 0x01: position.set(Position.KEY_ALARM, extendedAlarm ? Position.ALARM_SOS : Position.ALARM_GENERAL); break; + case 0x0E: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + break; + case 0x76: + position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); + break; case 0x80: position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); break; case 0x87: position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); break; + case 0x88: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; case 0x90: position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); break; @@ -959,7 +981,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); break; default: - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); break; } @@ -1432,6 +1453,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.OBD6; } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x29) { variant = Variant.WETRUST; + } else if (header == 0x7878 && type == MSG_ALARM && buf.getUnsignedShort(buf.readerIndex() + 4) == 0xffff) { + variant = Variant.JC400; } else { variant = Variant.STANDARD; } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 40f268a9d..9b196e501 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78785995ffff01170719152013df0163d45f041ee52018be002f00876900004556454e545f3836323739383035303137353131325f30303030303030305f323032335f30375f32355f31385f33325f30355f31342e6d70340119d15a0d0a"), + Position.KEY_EVENT, 0x69); + verifyAttribute(decoder, binary( "787829a01707150f2d0ecd01635100041e96d000087c02d4020000912e000000000718798d000e0006ed3ce50d0a"), Position.KEY_IGNITION, false); -- cgit v1.2.3 From 3a5edf787fc4dc3fdb7caa30602dee1e5fab8157 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Aug 2023 07:41:21 -0700 Subject: Additional CB212-C1005 data --- src/main/java/org/traccar/helper/ObdDecoder.java | 36 ++++++++++++---------- .../traccar/protocol/CastelProtocolDecoder.java | 31 +++++++++++++++++-- .../protocol/CastelProtocolDecoderTest.java | 8 +++++ 3 files changed, 56 insertions(+), 19 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/helper/ObdDecoder.java b/src/main/java/org/traccar/helper/ObdDecoder.java index b22065f4e..3cbae334a 100644 --- a/src/main/java/org/traccar/helper/ObdDecoder.java +++ b/src/main/java/org/traccar/helper/ObdDecoder.java @@ -51,22 +51,7 @@ public final class ObdDecoder { StringBuilder codes = new StringBuilder(); for (int i = 0; i < value.length() / 4; i++) { int numValue = Integer.parseInt(value.substring(i * 4, (i + 1) * 4), 16); - codes.append(' '); - switch (numValue >> 14) { - case 1: - codes.append('C'); - break; - case 2: - codes.append('B'); - break; - case 3: - codes.append('U'); - break; - default: - codes.append('P'); - break; - } - codes.append(String.format("%04X", numValue & 0x3FFF)); + codes.append(' ').append(decodeCode(numValue)); } if (codes.length() > 0) { return createEntry(Position.KEY_DTCS, codes.toString().trim()); @@ -75,6 +60,25 @@ public final class ObdDecoder { } } + public static String decodeCode(int value) { + char prefix; + switch (value >> 14) { + case 1: + prefix = 'C'; + break; + case 2: + prefix = 'B'; + break; + case 3: + prefix = 'U'; + break; + default: + prefix = 'P'; + break; + } + return String.format("%c%04X", prefix, value & 0x3FFF); + } + public static Map.Entry decodeData(int pid, long value, boolean convert) { switch (pid) { case 0x04: diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 4aa65245b..4d56e40c9 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -284,15 +284,27 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { case 0x0C: position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); break; + case 0x0D: + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + break; case 0x0E: position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); break; + case 0x11: + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + break; + case 0x12: + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + break; case 0x16: position.set(Position.KEY_IGNITION, true); break; case 0x17: position.set(Position.KEY_IGNITION, false); break; + case 0x1C: + position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); + break; default: break; } @@ -359,9 +371,9 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { int alarmCount = buf.readUnsignedByte(); for (int i = 0; i < alarmCount; i++) { if (buf.readUnsignedByte() != 0) { - int alarm = buf.readUnsignedByte(); + int event = buf.readUnsignedByte(); for (Position p : positions) { - decodeAlarm(p, alarm); + decodeAlarm(p, event); } buf.readUnsignedShortLE(); // description buf.readUnsignedShortLE(); // threshold @@ -421,12 +433,25 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { return position; case MSG_SC_DTCS_PASSENGER: + case MSG_SC_DTCS_COMMERCIAL: position = createPosition(deviceSession); decodeStat(position, buf); buf.readUnsignedByte(); // flag - position.add(ObdDecoder.decodeCodes(ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())))); + + count = buf.readUnsignedByte(); + StringBuilder codes = new StringBuilder(); + for (int i = 0; i < count; i++) { + if (type == MSG_SC_DTCS_COMMERCIAL) { + codes.append(ObdDecoder.decodeCode(buf.readUnsignedShortLE())); + buf.readUnsignedByte(); // attribute + buf.readUnsignedByte(); // occurrence + } else { + codes.append(ObdDecoder.decodeCode(buf.readUnsignedShortLE())); + } + } + position.set(Position.KEY_DTCS, codes.toString().trim()); return position; diff --git a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java index e9cbac5ce..52c6a86a6 100644 --- a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -11,6 +11,14 @@ public class CastelProtocolDecoderTest extends ProtocolTest { var decoder = inject(new CastelProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "40404700043231335732303139303033353400000000000000400BBE723A5DEF723A5D000000000000000000000000000000000000030100011900030001012603030145C90D0A"), + Position.KEY_DTCS, "P0326"); + + verifyAttribute(decoder, binary( + "40404500033231334c323031373030303432320000000000004006e1ad205bf1ad205b48510f000000000050160000000000020400053f007c000083040001511346160d0a"), + Position.KEY_DTCS, "P1351"); + verifyAttribute(decoder, binary( "40403a00043231334744503230313830323133343300000000a002000001000001012011004d414c43333831434d4b4d353637313438c8fc0d0a"), Position.KEY_RESULT, "MALC381CMKM567148"); -- cgit v1.2.3 From 36d319a81dc3d2c12222cce012c1a1a307a865b2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Aug 2023 07:45:59 -0700 Subject: Remove unused import --- src/main/java/org/traccar/protocol/CastelProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 4d56e40c9..566d856bb 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -16,7 +16,6 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -- cgit v1.2.3 From f0799e255a582a61ca9de1eb715af8b9849cc81a Mon Sep 17 00:00:00 2001 From: Rodolfo Silva Date: Mon, 7 Aug 2023 10:50:32 -0300 Subject: fix: remove AMQP auto close connection --- src/main/java/org/traccar/forward/AmqpClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/AmqpClient.java b/src/main/java/org/traccar/forward/AmqpClient.java index 302aa664c..361cfffee 100644 --- a/src/main/java/org/traccar/forward/AmqpClient.java +++ b/src/main/java/org/traccar/forward/AmqpClient.java @@ -43,7 +43,8 @@ public class AmqpClient { throw new RuntimeException("Error while setting URI for RabbitMQ connection factory", e); } - try (Connection connection = factory.newConnection()) { + try { + Connection connection = factory.newConnection(); channel = connection.createChannel(); channel.exchangeDeclare(exchange, BuiltinExchangeType.TOPIC, true); } catch (IOException | TimeoutException e) { -- cgit v1.2.3 From ac2ca17894da7fd43432c63056f6abef4a7a611b Mon Sep 17 00:00:00 2001 From: Rodolfo Silva Date: Mon, 7 Aug 2023 12:05:06 -0300 Subject: fix: add shutdown hook to close the AMQP connection --- src/main/java/org/traccar/forward/AmqpClient.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/AmqpClient.java b/src/main/java/org/traccar/forward/AmqpClient.java index 361cfffee..8ac618f5c 100644 --- a/src/main/java/org/traccar/forward/AmqpClient.java +++ b/src/main/java/org/traccar/forward/AmqpClient.java @@ -47,6 +47,13 @@ public class AmqpClient { Connection connection = factory.newConnection(); channel = connection.createChannel(); channel.exchangeDeclare(exchange, BuiltinExchangeType.TOPIC, true); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + connection.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + })); } catch (IOException | TimeoutException e) { throw new RuntimeException("Error while creating and configuring RabbitMQ channel", e); } -- cgit v1.2.3 From 78ead877bac40cd88fc342e966741b42568de5a5 Mon Sep 17 00:00:00 2001 From: Rodolfo Silva Date: Mon, 7 Aug 2023 16:47:56 -0300 Subject: fix: remove the AmqpClient shutdown hook --- src/main/java/org/traccar/forward/AmqpClient.java | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/forward/AmqpClient.java b/src/main/java/org/traccar/forward/AmqpClient.java index 8ac618f5c..361cfffee 100644 --- a/src/main/java/org/traccar/forward/AmqpClient.java +++ b/src/main/java/org/traccar/forward/AmqpClient.java @@ -47,13 +47,6 @@ public class AmqpClient { Connection connection = factory.newConnection(); channel = connection.createChannel(); channel.exchangeDeclare(exchange, BuiltinExchangeType.TOPIC, true); - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - try { - connection.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - })); } catch (IOException | TimeoutException e) { throw new RuntimeException("Error while creating and configuring RabbitMQ channel", e); } -- cgit v1.2.3 From 08a3f9c4530d072a224037eaa8683195c4233f84 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Aug 2023 07:44:29 -0700 Subject: Support SL22 SL24 SL28 devices --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 53c812bb7..56a915e7d 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -916,7 +916,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - if (type == MSG_GPS_LBS_7) { + if (buf.readableBytes() == 3 + 6 || buf.readableBytes() == 3 + 4 + 6) { position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); buf.readUnsignedByte(); // upload mode position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0 ? true : null); -- cgit v1.2.3 From 7d53ddabd857330cd9791b12484d925857842cc9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Aug 2023 08:23:40 -0700 Subject: Support SL42 SL44 SL48 devices --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 43 ++++++++++++++-------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 56a915e7d..161d04d8d 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -78,11 +78,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_HEARTBEAT = 0x23; // GK310 public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 - public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 - public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 - public static final int MSG_WIFI_5 = 0x33; // AZ735 - public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended - public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended + public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 & SL4X + public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 & SL4X + public static final int MSG_WIFI_5 = 0x33; // AZ735 & SL4X + public static final int MSG_LBS_3 = 0x34; // SL4X + public static final int MSG_AZ735_GPS = 0x32; // AZ735 (extended) + public static final int MSG_AZ735_ALARM = 0x33; // AZ735 (only extended) public static final int MSG_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; @@ -122,6 +123,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { OBD6, WETRUST, JC400, + SL4X, } private Variant variant; @@ -549,7 +551,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; - } else if (type == MSG_X1_GPS) { + } else if (type == MSG_X1_GPS && variant != Variant.SL4X) { buf.readUnsignedInt(); // data and alarm @@ -682,41 +684,50 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 - || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 + || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_LBS_3 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { - boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5; - DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); getLastLocation(position, dateBuilder.getDate()); - if (variant == Variant.WANWAY_S20) { + if (variant == Variant.WANWAY_S20 || variant == Variant.SL4X) { buf.readUnsignedByte(); // ta } int mcc = buf.readUnsignedShort(); - int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); + int mnc = BitUtil.check(mcc, 15) || variant == Variant.SL4X + ? buf.readUnsignedShort() : buf.readUnsignedByte(); Network network = new Network(); int cellCount = variant == Variant.WANWAY_S20 ? buf.readUnsignedByte() : type == MSG_WIFI_5 ? 6 : 7; for (int i = 0; i < cellCount; i++) { - int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); - int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); + int lac; + int cid; + if (type == MSG_LBS_2 || type == MSG_WIFI_3) { + lac = buf.readInt(); + cid = (int) buf.readLong(); + } else if (type == MSG_WIFI_5 || type == MSG_LBS_3) { + lac = buf.readUnsignedShort(); + cid = (int) buf.readUnsignedInt(); + } else { + lac = buf.readUnsignedShort(); + cid = buf.readUnsignedMedium(); + } int rssi = -buf.readUnsignedByte(); if (lac > 0) { network.addCellTower(CellTower.from(BitUtil.to(mcc, 15), mnc, lac, cid, rssi)); } } - if (variant != Variant.WANWAY_S20) { + if (variant != Variant.WANWAY_S20 && variant != Variant.SL4X) { buf.readUnsignedByte(); // ta } if (type != MSG_LBS_MULTIPLE_1 && type != MSG_LBS_MULTIPLE_2 && type != MSG_LBS_MULTIPLE_3 - && type != MSG_LBS_2) { + && type != MSG_LBS_2 && type != MSG_LBS_3) { int wifiCount = buf.readUnsignedByte(); for (int i = 0; i < wifiCount; i++) { String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); @@ -1455,6 +1466,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.WETRUST; } else if (header == 0x7878 && type == MSG_ALARM && buf.getUnsignedShort(buf.readerIndex() + 4) == 0xffff) { variant = Variant.JC400; + } else if (header == 0x7878 && type == MSG_LBS_3 && length == 0x37) { + variant = Variant.SL4X; } else { variant = Variant.STANDARD; } -- cgit v1.2.3 From 25c8da353ead804eabb5b3388f711f20585feff3 Mon Sep 17 00:00:00 2001 From: Jamie Guthrie Date: Tue, 15 Aug 2023 12:45:46 +0200 Subject: Throw overspeed event immediately, accounting for minimumDuration --- .../traccar/session/state/OverspeedProcessor.java | 37 ++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/state/OverspeedProcessor.java b/src/main/java/org/traccar/session/state/OverspeedProcessor.java index 62f6a3de2..a6cd72322 100644 --- a/src/main/java/org/traccar/session/state/OverspeedProcessor.java +++ b/src/main/java/org/traccar/session/state/OverspeedProcessor.java @@ -34,22 +34,7 @@ public final class OverspeedProcessor { if (oldState) { boolean newState = position.getSpeed() > speedLimit; if (newState) { - if (state.getOverspeedTime() != null) { - long oldTime = state.getOverspeedTime().getTime(); - long newTime = position.getFixTime().getTime(); - if (newTime - oldTime > minimalDuration) { - - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); - event.set(ATTRIBUTE_SPEED, position.getSpeed()); - event.set(Position.KEY_SPEED_LIMIT, speedLimit); - event.setGeofenceId(state.getOverspeedGeofenceId()); - - state.setOverspeedTime(null); - state.setOverspeedGeofenceId(0); - state.setEvent(event); - - } - } + setEvent(state, position, speedLimit, minimalDuration); } else { state.setOverspeedState(false); state.setOverspeedTime(null); @@ -59,7 +44,27 @@ public final class OverspeedProcessor { state.setOverspeedState(true); state.setOverspeedTime(position.getFixTime()); state.setOverspeedGeofenceId(geofenceId); + + setEvent(state, position, speedLimit, minimalDuration); } } + private static void setEvent(OverspeedState state, Position position, double speedLimit, long minimalDuration) { + if (state.getOverspeedTime() != null) { + long oldTime = state.getOverspeedTime().getTime(); + long newTime = position.getFixTime().getTime(); + if (newTime - oldTime >= minimalDuration) { + + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); + event.set(ATTRIBUTE_SPEED, position.getSpeed()); + event.set(Position.KEY_SPEED_LIMIT, speedLimit); + event.setGeofenceId(state.getOverspeedGeofenceId()); + + state.setOverspeedTime(null); + state.setOverspeedGeofenceId(0); + state.setEvent(event); + + } + } + } } -- cgit v1.2.3 From 95059cb3db832a26c6dbf3706aded3a2ffbcf3d8 Mon Sep 17 00:00:00 2001 From: Jamie Guthrie Date: Tue, 15 Aug 2023 21:20:21 +0200 Subject: Rename setEvent method to checkEvent --- src/main/java/org/traccar/session/state/OverspeedProcessor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/session/state/OverspeedProcessor.java b/src/main/java/org/traccar/session/state/OverspeedProcessor.java index a6cd72322..b23649570 100644 --- a/src/main/java/org/traccar/session/state/OverspeedProcessor.java +++ b/src/main/java/org/traccar/session/state/OverspeedProcessor.java @@ -34,7 +34,7 @@ public final class OverspeedProcessor { if (oldState) { boolean newState = position.getSpeed() > speedLimit; if (newState) { - setEvent(state, position, speedLimit, minimalDuration); + checkEvent(state, position, speedLimit, minimalDuration); } else { state.setOverspeedState(false); state.setOverspeedTime(null); @@ -45,11 +45,11 @@ public final class OverspeedProcessor { state.setOverspeedTime(position.getFixTime()); state.setOverspeedGeofenceId(geofenceId); - setEvent(state, position, speedLimit, minimalDuration); + checkEvent(state, position, speedLimit, minimalDuration); } } - private static void setEvent(OverspeedState state, Position position, double speedLimit, long minimalDuration) { + private static void checkEvent(OverspeedState state, Position position, double speedLimit, long minimalDuration) { if (state.getOverspeedTime() != null) { long oldTime = state.getOverspeedTime().getTime(); long newTime = position.getFixTime().getTime(); -- cgit v1.2.3 From a1c12c50a8d0023d6ccfbf4eb0723a90eab55cc5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 17 Aug 2023 06:56:58 -0700 Subject: Disable for UDP protocols --- src/main/java/org/traccar/BasePipelineFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index d04fed383..5b48f3d15 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -125,7 +125,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { } pipeline.addLast(new NetworkMessageHandler()); pipeline.addLast(new StandardLoggingHandler(protocol)); - if (!config.getBoolean(Keys.SERVER_INSTANT_ACKNOWLEDGEMENT)) { + if (!connector.isDatagram() && !config.getBoolean(Keys.SERVER_INSTANT_ACKNOWLEDGEMENT)) { pipeline.addLast(new AcknowledgementHandler()); } -- cgit v1.2.3 From 51712e33c363d5150cfd690d6f3c466a38ab6ba3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2023 10:32:35 -0700 Subject: Support statistics attributes --- src/main/java/org/traccar/database/StatisticsManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index e417c8901..0e9931fba 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -100,6 +100,8 @@ public class StatisticsManager { statistics.setProtocols(protocols); } + statistics.set("modern", config.getString(Keys.WEB_PATH).contains("modern")); + users.clear(); deviceProtocols.clear(); deviceMessages.clear(); @@ -141,6 +143,13 @@ public class StatisticsManager { LOGGER.warn("Failed to serialize protocols", e); } } + if (!statistics.getAttributes().isEmpty()) { + try { + form.param("attributes", objectMapper.writeValueAsString(statistics.getAttributes())); + } catch (JsonProcessingException e) { + LOGGER.warn("Failed to serialize attributes", e); + } + } client.target(url).request().async().post(Entity.form(form)); } -- cgit v1.2.3 From 9df5d93ba0482b628d05b10c29100144beed5b5d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2023 13:25:39 -0700 Subject: Move from javax to jakarta --- build.gradle | 50 +++++++++++----------- src/main/java/org/traccar/BaseProtocol.java | 4 +- src/main/java/org/traccar/BaseProtocolDecoder.java | 2 +- src/main/java/org/traccar/BaseProtocolEncoder.java | 2 +- .../java/org/traccar/ExtendedObjectDecoder.java | 2 +- src/main/java/org/traccar/MainEventHandler.java | 4 +- src/main/java/org/traccar/MainModule.java | 12 +++--- .../org/traccar/PositionForwardingHandler.java | 6 +-- src/main/java/org/traccar/ServerManager.java | 4 +- .../java/org/traccar/api/AsyncSocketServlet.java | 6 +-- .../java/org/traccar/api/BaseObjectResource.java | 16 +++---- src/main/java/org/traccar/api/BaseResource.java | 6 +-- .../java/org/traccar/api/CorsResponseFilter.java | 10 ++--- .../api/DateParameterConverterProvider.java | 4 +- .../org/traccar/api/ExtendedObjectResource.java | 4 +- src/main/java/org/traccar/api/MediaFilter.java | 20 ++++----- .../java/org/traccar/api/ResourceErrorHandler.java | 6 +-- .../java/org/traccar/api/SimpleObjectResource.java | 4 +- .../traccar/api/resource/AttributeResource.java | 22 +++++----- .../org/traccar/api/resource/CalendarResource.java | 8 ++-- .../org/traccar/api/resource/CommandResource.java | 18 ++++---- .../org/traccar/api/resource/DeviceResource.java | 26 +++++------ .../org/traccar/api/resource/DriverResource.java | 8 ++-- .../org/traccar/api/resource/EventResource.java | 16 +++---- .../org/traccar/api/resource/GeofenceResource.java | 8 ++-- .../org/traccar/api/resource/GroupResource.java | 8 ++-- .../traccar/api/resource/MaintenanceResource.java | 8 ++-- .../traccar/api/resource/NotificationResource.java | 18 ++++---- .../org/traccar/api/resource/OrderResource.java | 8 ++-- .../org/traccar/api/resource/PasswordResource.java | 20 ++++----- .../traccar/api/resource/PermissionsResource.java | 18 ++++---- .../org/traccar/api/resource/PositionResource.java | 24 +++++------ .../org/traccar/api/resource/ReportResource.java | 24 +++++------ .../org/traccar/api/resource/ServerResource.java | 26 +++++------ .../org/traccar/api/resource/SessionResource.java | 36 ++++++++-------- .../traccar/api/resource/StatisticsResource.java | 12 +++--- .../org/traccar/api/resource/UserResource.java | 20 ++++----- .../org/traccar/api/security/LoginService.java | 6 +-- .../traccar/api/security/PermissionsService.java | 2 +- .../api/security/SecurityRequestFilter.java | 20 ++++----- .../traccar/api/security/UserSecurityContext.java | 2 +- .../org/traccar/api/signature/CryptoManager.java | 4 +- .../org/traccar/api/signature/TokenManager.java | 4 +- src/main/java/org/traccar/config/Config.java | 4 +- .../java/org/traccar/database/CommandsManager.java | 6 +-- .../org/traccar/database/DeviceLookupService.java | 4 +- .../java/org/traccar/database/MediaManager.java | 4 +- .../org/traccar/database/NotificationManager.java | 6 +-- .../java/org/traccar/database/OpenIdProvider.java | 2 +- .../org/traccar/database/StatisticsManager.java | 10 ++--- .../org/traccar/forward/EventForwarderJson.java | 8 ++-- .../java/org/traccar/forward/NetworkForwarder.java | 4 +- .../org/traccar/forward/PositionForwarderJson.java | 12 +++--- .../org/traccar/forward/PositionForwarderUrl.java | 6 +-- .../java/org/traccar/geocoder/BanGeocoder.java | 6 +-- .../org/traccar/geocoder/BingMapsGeocoder.java | 6 +-- .../java/org/traccar/geocoder/FactualGeocoder.java | 4 +- .../org/traccar/geocoder/GeoapifyGeocoder.java | 6 +-- .../org/traccar/geocoder/GeocodeFarmGeocoder.java | 4 +- .../org/traccar/geocoder/GeocodeXyzGeocoder.java | 4 +- .../org/traccar/geocoder/GisgraphyGeocoder.java | 4 +- .../java/org/traccar/geocoder/GoogleGeocoder.java | 8 ++-- .../java/org/traccar/geocoder/HereGeocoder.java | 4 +- .../java/org/traccar/geocoder/JsonGeocoder.java | 8 ++-- .../org/traccar/geocoder/LocationIqGeocoder.java | 2 +- .../org/traccar/geocoder/MapQuestGeocoder.java | 6 +-- .../org/traccar/geocoder/MapTilerGeocoder.java | 6 +-- .../java/org/traccar/geocoder/MapboxGeocoder.java | 8 ++-- .../org/traccar/geocoder/MapmyIndiaGeocoder.java | 6 +-- .../org/traccar/geocoder/NominatimGeocoder.java | 4 +- .../org/traccar/geocoder/OpenCageGeocoder.java | 6 +-- .../traccar/geocoder/PositionStackGeocoder.java | 6 +-- .../java/org/traccar/geocoder/TomTomGeocoder.java | 6 +-- .../geolocation/GoogleGeolocationProvider.java | 2 +- .../geolocation/MozillaGeolocationProvider.java | 2 +- .../geolocation/OpenCellIdGeolocationProvider.java | 6 +-- .../geolocation/UniversalGeolocationProvider.java | 8 ++-- .../geolocation/UnwiredGeolocationProvider.java | 8 ++-- .../traccar/handler/ComputedAttributesHandler.java | 4 +- .../org/traccar/handler/CopyAttributesHandler.java | 4 +- .../org/traccar/handler/DefaultDataHandler.java | 4 +- .../java/org/traccar/handler/DistanceHandler.java | 4 +- .../org/traccar/handler/EngineHoursHandler.java | 4 +- .../java/org/traccar/handler/FilterHandler.java | 4 +- .../java/org/traccar/handler/GeofenceHandler.java | 4 +- .../org/traccar/handler/HemisphereHandler.java | 4 +- .../java/org/traccar/handler/MotionHandler.java | 4 +- .../traccar/handler/NetworkForwarderHandler.java | 2 +- .../org/traccar/handler/RemoteAddressHandler.java | 4 +- .../org/traccar/handler/SpeedLimitHandler.java | 4 +- src/main/java/org/traccar/handler/TimeHandler.java | 4 +- .../traccar/handler/events/AlertEventHandler.java | 4 +- .../traccar/handler/events/BaseEventHandler.java | 2 +- .../handler/events/BehaviorEventHandler.java | 4 +- .../handler/events/CommandResultEventHandler.java | 4 +- .../traccar/handler/events/DriverEventHandler.java | 4 +- .../traccar/handler/events/FuelEventHandler.java | 4 +- .../handler/events/GeofenceEventHandler.java | 4 +- .../handler/events/IgnitionEventHandler.java | 4 +- .../handler/events/MaintenanceEventHandler.java | 4 +- .../traccar/handler/events/MediaEventHandler.java | 4 +- .../traccar/handler/events/MotionEventHandler.java | 4 +- .../handler/events/OverspeedEventHandler.java | 4 +- .../helper/ObjectMapperContextResolver.java | 4 +- src/main/java/org/traccar/helper/WebHelper.java | 2 +- src/main/java/org/traccar/mail/LogMailManager.java | 4 +- src/main/java/org/traccar/mail/MailManager.java | 4 +- .../java/org/traccar/mail/SmtpMailManager.java | 20 ++++----- .../notification/NotificationFormatter.java | 4 +- .../traccar/notification/NotificatorManager.java | 4 +- .../notification/TextTemplateFormatter.java | 4 +- .../traccar/notificators/NotificatorCommand.java | 4 +- .../traccar/notificators/NotificatorFirebase.java | 4 +- .../org/traccar/notificators/NotificatorMail.java | 6 +-- .../traccar/notificators/NotificatorPushover.java | 8 ++-- .../org/traccar/notificators/NotificatorSms.java | 4 +- .../traccar/notificators/NotificatorTelegram.java | 8 ++-- .../traccar/notificators/NotificatorTraccar.java | 12 +++--- .../org/traccar/notificators/NotificatorWeb.java | 4 +- .../java/org/traccar/protocol/AdmProtocol.java | 2 +- .../java/org/traccar/protocol/AisProtocol.java | 2 +- .../org/traccar/protocol/AlematicsProtocol.java | 2 +- .../java/org/traccar/protocol/AnytrekProtocol.java | 2 +- .../java/org/traccar/protocol/ApelProtocol.java | 2 +- .../java/org/traccar/protocol/AplicomProtocol.java | 2 +- .../java/org/traccar/protocol/AppelloProtocol.java | 2 +- .../java/org/traccar/protocol/AquilaProtocol.java | 2 +- .../java/org/traccar/protocol/Ardi01Protocol.java | 2 +- .../java/org/traccar/protocol/ArknavProtocol.java | 2 +- .../org/traccar/protocol/ArknavX8Protocol.java | 2 +- .../java/org/traccar/protocol/ArmoliProtocol.java | 2 +- .../java/org/traccar/protocol/ArnaviProtocol.java | 2 +- .../traccar/protocol/ArnaviProtocolDecoder.java | 2 +- .../java/org/traccar/protocol/AstraProtocol.java | 2 +- .../java/org/traccar/protocol/At2000Protocol.java | 2 +- .../java/org/traccar/protocol/AtrackProtocol.java | 2 +- .../java/org/traccar/protocol/AuroProtocol.java | 2 +- .../org/traccar/protocol/AustinNbProtocol.java | 2 +- .../java/org/traccar/protocol/AutoFonProtocol.java | 2 +- .../org/traccar/protocol/AutoGradeProtocol.java | 2 +- .../org/traccar/protocol/AutoTrackProtocol.java | 2 +- .../java/org/traccar/protocol/AvemaProtocol.java | 2 +- .../java/org/traccar/protocol/Avl301Protocol.java | 2 +- .../java/org/traccar/protocol/B2316Protocol.java | 2 +- .../org/traccar/protocol/B2316ProtocolDecoder.java | 6 +-- .../java/org/traccar/protocol/BceProtocol.java | 2 +- .../org/traccar/protocol/BlackKiteProtocol.java | 2 +- .../java/org/traccar/protocol/BlueProtocol.java | 2 +- .../java/org/traccar/protocol/BoxProtocol.java | 2 +- .../java/org/traccar/protocol/BstplProtocol.java | 2 +- .../java/org/traccar/protocol/C2stekProtocol.java | 2 +- .../java/org/traccar/protocol/CalAmpProtocol.java | 2 +- .../org/traccar/protocol/CarTrackProtocol.java | 2 +- .../java/org/traccar/protocol/CarcellProtocol.java | 2 +- .../java/org/traccar/protocol/CarscopProtocol.java | 2 +- .../java/org/traccar/protocol/CastelProtocol.java | 2 +- .../java/org/traccar/protocol/CautelaProtocol.java | 2 +- .../org/traccar/protocol/CellocatorProtocol.java | 2 +- .../java/org/traccar/protocol/CguardProtocol.java | 2 +- .../org/traccar/protocol/CityeasyProtocol.java | 2 +- .../org/traccar/protocol/ContinentalProtocol.java | 2 +- .../org/traccar/protocol/CradlepointProtocol.java | 2 +- .../java/org/traccar/protocol/DingtekProtocol.java | 2 +- .../java/org/traccar/protocol/DishaProtocol.java | 2 +- .../java/org/traccar/protocol/DmtHttpProtocol.java | 2 +- .../traccar/protocol/DmtHttpProtocolDecoder.java | 6 +-- .../java/org/traccar/protocol/DmtProtocol.java | 2 +- .../java/org/traccar/protocol/DolphinProtocol.java | 2 +- .../java/org/traccar/protocol/Dsf22Protocol.java | 2 +- .../java/org/traccar/protocol/DualcamProtocol.java | 2 +- .../java/org/traccar/protocol/DwayProtocol.java | 2 +- .../org/traccar/protocol/EasyTrackProtocol.java | 2 +- .../java/org/traccar/protocol/EelinkProtocol.java | 2 +- .../java/org/traccar/protocol/EgtsProtocol.java | 2 +- .../java/org/traccar/protocol/EnforaProtocol.java | 2 +- .../java/org/traccar/protocol/EnnfuProtocol.java | 2 +- .../org/traccar/protocol/EnvotechProtocol.java | 2 +- .../java/org/traccar/protocol/EsealProtocol.java | 2 +- .../java/org/traccar/protocol/EskyProtocol.java | 2 +- .../org/traccar/protocol/ExtremTracProtocol.java | 2 +- .../org/traccar/protocol/FifotrackProtocol.java | 2 +- .../java/org/traccar/protocol/FlespiProtocol.java | 2 +- .../traccar/protocol/FlespiProtocolDecoder.java | 12 +++--- .../java/org/traccar/protocol/FlexApiProtocol.java | 2 +- .../traccar/protocol/FlexApiProtocolDecoder.java | 4 +- .../org/traccar/protocol/FlexCommProtocol.java | 2 +- .../traccar/protocol/FlexibleReportProtocol.java | 2 +- .../org/traccar/protocol/FlextrackProtocol.java | 2 +- .../java/org/traccar/protocol/FoxProtocol.java | 2 +- .../java/org/traccar/protocol/FreedomProtocol.java | 2 +- .../org/traccar/protocol/FreematicsProtocol.java | 2 +- .../org/traccar/protocol/FutureWayProtocol.java | 2 +- .../java/org/traccar/protocol/G1rusProtocol.java | 2 +- .../java/org/traccar/protocol/GalileoProtocol.java | 2 +- .../java/org/traccar/protocol/GatorProtocol.java | 2 +- .../java/org/traccar/protocol/GenxProtocol.java | 2 +- .../java/org/traccar/protocol/Gl100Protocol.java | 2 +- .../java/org/traccar/protocol/Gl200Protocol.java | 2 +- .../org/traccar/protocol/Gl200ProtocolDecoder.java | 2 +- .../org/traccar/protocol/GlobalSatProtocol.java | 2 +- .../org/traccar/protocol/GlobalstarProtocol.java | 2 +- .../java/org/traccar/protocol/GnxProtocol.java | 2 +- .../java/org/traccar/protocol/GoSafeProtocol.java | 2 +- .../java/org/traccar/protocol/GotopProtocol.java | 2 +- .../java/org/traccar/protocol/Gps056Protocol.java | 2 +- .../java/org/traccar/protocol/Gps103Protocol.java | 2 +- .../java/org/traccar/protocol/GpsGateProtocol.java | 2 +- .../org/traccar/protocol/GpsMarkerProtocol.java | 2 +- .../java/org/traccar/protocol/GpsmtaProtocol.java | 2 +- .../java/org/traccar/protocol/GranitProtocol.java | 2 +- .../java/org/traccar/protocol/Gs100Protocol.java | 2 +- .../java/org/traccar/protocol/Gt02Protocol.java | 2 +- .../java/org/traccar/protocol/Gt06Protocol.java | 2 +- .../java/org/traccar/protocol/Gt30Protocol.java | 2 +- .../java/org/traccar/protocol/H02Protocol.java | 2 +- .../java/org/traccar/protocol/HaicomProtocol.java | 2 +- .../java/org/traccar/protocol/HomtecsProtocol.java | 2 +- .../java/org/traccar/protocol/HoopoProtocol.java | 2 +- .../org/traccar/protocol/HoopoProtocolDecoder.java | 4 +- .../org/traccar/protocol/HuaShengProtocol.java | 2 +- .../java/org/traccar/protocol/HuabaoProtocol.java | 2 +- .../org/traccar/protocol/HunterProProtocol.java | 2 +- .../java/org/traccar/protocol/IdplProtocol.java | 2 +- .../org/traccar/protocol/IntellitracProtocol.java | 2 +- .../java/org/traccar/protocol/IotmProtocol.java | 2 +- .../java/org/traccar/protocol/ItsProtocol.java | 2 +- .../java/org/traccar/protocol/Ivt401Protocol.java | 2 +- .../java/org/traccar/protocol/JidoProtocol.java | 2 +- .../org/traccar/protocol/JpKorjarProtocol.java | 2 +- .../java/org/traccar/protocol/Jt600Protocol.java | 2 +- .../java/org/traccar/protocol/KenjiProtocol.java | 2 +- .../java/org/traccar/protocol/KhdProtocol.java | 2 +- .../java/org/traccar/protocol/L100Protocol.java | 2 +- .../java/org/traccar/protocol/LacakProtocol.java | 2 +- .../org/traccar/protocol/LacakProtocolDecoder.java | 4 +- .../java/org/traccar/protocol/LaipacProtocol.java | 2 +- .../java/org/traccar/protocol/LeafSpyProtocol.java | 2 +- .../java/org/traccar/protocol/M2cProtocol.java | 2 +- .../java/org/traccar/protocol/M2mProtocol.java | 2 +- .../java/org/traccar/protocol/MaestroProtocol.java | 2 +- .../org/traccar/protocol/ManPowerProtocol.java | 2 +- .../org/traccar/protocol/Mavlink2Protocol.java | 2 +- .../org/traccar/protocol/MegastekProtocol.java | 2 +- .../org/traccar/protocol/MeiligaoProtocol.java | 2 +- .../org/traccar/protocol/MeitrackProtocol.java | 2 +- .../org/traccar/protocol/MictrackProtocol.java | 2 +- .../org/traccar/protocol/MilesmateProtocol.java | 2 +- .../org/traccar/protocol/MiniFinderProtocol.java | 2 +- .../org/traccar/protocol/Minifinder2Protocol.java | 2 +- .../org/traccar/protocol/MobilogixProtocol.java | 2 +- .../java/org/traccar/protocol/MoovboxProtocol.java | 2 +- .../java/org/traccar/protocol/MotorProtocol.java | 2 +- .../java/org/traccar/protocol/Mta6Protocol.java | 2 +- .../java/org/traccar/protocol/MtxProtocol.java | 2 +- .../java/org/traccar/protocol/MxtProtocol.java | 2 +- .../java/org/traccar/protocol/NavigilProtocol.java | 2 +- .../java/org/traccar/protocol/NavisProtocol.java | 2 +- .../java/org/traccar/protocol/NavisetProtocol.java | 2 +- .../org/traccar/protocol/NavtelecomProtocol.java | 2 +- .../java/org/traccar/protocol/NdtpV6Protocol.java | 2 +- .../java/org/traccar/protocol/NeosProtocol.java | 2 +- .../java/org/traccar/protocol/NetProtocol.java | 2 +- .../java/org/traccar/protocol/NiotProtocol.java | 2 +- .../java/org/traccar/protocol/NoranProtocol.java | 2 +- .../java/org/traccar/protocol/NvsProtocol.java | 2 +- .../java/org/traccar/protocol/NyitechProtocol.java | 2 +- .../org/traccar/protocol/ObdDongleProtocol.java | 2 +- .../java/org/traccar/protocol/OigoProtocol.java | 2 +- .../java/org/traccar/protocol/OkoProtocol.java | 2 +- .../org/traccar/protocol/OmnicommProtocol.java | 2 +- .../java/org/traccar/protocol/OpenGtsProtocol.java | 2 +- .../java/org/traccar/protocol/OrbcommProtocol.java | 2 +- .../traccar/protocol/OrbcommProtocolDecoder.java | 8 ++-- .../java/org/traccar/protocol/OrionProtocol.java | 2 +- .../java/org/traccar/protocol/OsmAndProtocol.java | 2 +- .../java/org/traccar/protocol/OutsafeProtocol.java | 2 +- .../traccar/protocol/OutsafeProtocolDecoder.java | 10 ++--- .../org/traccar/protocol/OwnTracksProtocol.java | 2 +- .../traccar/protocol/OwnTracksProtocolDecoder.java | 4 +- .../org/traccar/protocol/PacificTrackProtocol.java | 2 +- .../org/traccar/protocol/PathAwayProtocol.java | 2 +- .../org/traccar/protocol/PiligrimProtocol.java | 2 +- .../java/org/traccar/protocol/PluginProtocol.java | 2 +- .../java/org/traccar/protocol/PolteProtocol.java | 2 +- .../org/traccar/protocol/PolteProtocolDecoder.java | 4 +- .../java/org/traccar/protocol/PortmanProtocol.java | 2 +- .../org/traccar/protocol/PretraceProtocol.java | 2 +- .../java/org/traccar/protocol/PricolProtocol.java | 2 +- .../org/traccar/protocol/ProgressProtocol.java | 2 +- .../java/org/traccar/protocol/PstProtocol.java | 2 +- .../java/org/traccar/protocol/Pt215Protocol.java | 2 +- .../java/org/traccar/protocol/Pt3000Protocol.java | 2 +- .../java/org/traccar/protocol/Pt502Protocol.java | 2 +- .../java/org/traccar/protocol/Pt60Protocol.java | 2 +- .../java/org/traccar/protocol/R12wProtocol.java | 2 +- .../org/traccar/protocol/RaceDynamicsProtocol.java | 2 +- .../java/org/traccar/protocol/RadarProtocol.java | 2 +- .../java/org/traccar/protocol/RaveonProtocol.java | 2 +- .../java/org/traccar/protocol/RecodaProtocol.java | 2 +- .../org/traccar/protocol/RetranslatorProtocol.java | 2 +- .../java/org/traccar/protocol/RfTrackProtocol.java | 2 +- .../traccar/protocol/RfTrackProtocolDecoder.java | 6 +-- .../java/org/traccar/protocol/RitiProtocol.java | 2 +- .../org/traccar/protocol/RoboTrackProtocol.java | 2 +- .../java/org/traccar/protocol/RstProtocol.java | 2 +- .../java/org/traccar/protocol/RuptelaProtocol.java | 2 +- .../java/org/traccar/protocol/S168Protocol.java | 2 +- .../org/traccar/protocol/SabertekProtocol.java | 2 +- .../java/org/traccar/protocol/SanavProtocol.java | 2 +- .../java/org/traccar/protocol/SanulProtocol.java | 2 +- .../java/org/traccar/protocol/SatsolProtocol.java | 2 +- .../java/org/traccar/protocol/SigfoxProtocol.java | 2 +- .../traccar/protocol/SigfoxProtocolDecoder.java | 10 ++--- .../java/org/traccar/protocol/SiwiProtocol.java | 2 +- .../org/traccar/protocol/SkypatrolProtocol.java | 2 +- .../org/traccar/protocol/SmartSoleProtocol.java | 2 +- .../java/org/traccar/protocol/SmokeyProtocol.java | 2 +- .../org/traccar/protocol/SolarPoweredProtocol.java | 2 +- .../java/org/traccar/protocol/SpotProtocol.java | 2 +- .../org/traccar/protocol/StarLinkProtocol.java | 2 +- .../java/org/traccar/protocol/StarcomProtocol.java | 2 +- .../java/org/traccar/protocol/StartekProtocol.java | 2 +- .../java/org/traccar/protocol/StbProtocol.java | 2 +- .../org/traccar/protocol/StbProtocolDecoder.java | 6 +-- .../java/org/traccar/protocol/Stl060Protocol.java | 2 +- .../java/org/traccar/protocol/SuntechProtocol.java | 2 +- .../org/traccar/protocol/SupermateProtocol.java | 2 +- .../java/org/traccar/protocol/SviasProtocol.java | 2 +- .../org/traccar/protocol/SwiftechProtocol.java | 2 +- .../java/org/traccar/protocol/T55Protocol.java | 2 +- .../java/org/traccar/protocol/T57Protocol.java | 2 +- .../org/traccar/protocol/T622IridiumProtocol.java | 2 +- .../java/org/traccar/protocol/T800xProtocol.java | 2 +- .../java/org/traccar/protocol/TaipProtocol.java | 2 +- .../java/org/traccar/protocol/TechTltProtocol.java | 2 +- .../org/traccar/protocol/TechtoCruzProtocol.java | 2 +- .../java/org/traccar/protocol/TekProtocol.java | 2 +- .../java/org/traccar/protocol/TelemaxProtocol.java | 2 +- .../java/org/traccar/protocol/TelicProtocol.java | 2 +- .../org/traccar/protocol/TeltonikaProtocol.java | 2 +- .../org/traccar/protocol/TeraTrackProtocol.java | 2 +- .../traccar/protocol/TeraTrackProtocolDecoder.java | 4 +- .../org/traccar/protocol/ThinkPowerProtocol.java | 2 +- .../org/traccar/protocol/ThinkRaceProtocol.java | 2 +- .../java/org/traccar/protocol/ThurayaProtocol.java | 2 +- .../java/org/traccar/protocol/Tk102Protocol.java | 2 +- .../java/org/traccar/protocol/Tk103Protocol.java | 2 +- .../java/org/traccar/protocol/Tlt2hProtocol.java | 2 +- .../java/org/traccar/protocol/TlvProtocol.java | 2 +- .../java/org/traccar/protocol/TmgProtocol.java | 2 +- .../org/traccar/protocol/TopflytechProtocol.java | 2 +- .../java/org/traccar/protocol/TopinProtocol.java | 2 +- .../java/org/traccar/protocol/TotemProtocol.java | 2 +- .../java/org/traccar/protocol/Tr20Protocol.java | 2 +- .../java/org/traccar/protocol/Tr900Protocol.java | 2 +- .../org/traccar/protocol/TrackboxProtocol.java | 2 +- .../org/traccar/protocol/TrakMateProtocol.java | 2 +- .../java/org/traccar/protocol/TramigoProtocol.java | 2 +- .../org/traccar/protocol/TranSyncProtocol.java | 2 +- .../java/org/traccar/protocol/TrvProtocol.java | 2 +- .../java/org/traccar/protocol/Tt8850Protocol.java | 2 +- .../java/org/traccar/protocol/TytanProtocol.java | 2 +- .../java/org/traccar/protocol/TzoneProtocol.java | 2 +- .../org/traccar/protocol/UlbotechProtocol.java | 2 +- .../java/org/traccar/protocol/UproProtocol.java | 2 +- .../java/org/traccar/protocol/UuxProtocol.java | 2 +- .../java/org/traccar/protocol/V680Protocol.java | 2 +- .../org/traccar/protocol/VisiontekProtocol.java | 2 +- .../java/org/traccar/protocol/VltProtocol.java | 2 +- .../java/org/traccar/protocol/VnetProtocol.java | 2 +- .../java/org/traccar/protocol/Vt200Protocol.java | 2 +- .../java/org/traccar/protocol/VtfmsProtocol.java | 2 +- .../java/org/traccar/protocol/WatchProtocol.java | 2 +- .../java/org/traccar/protocol/WialonProtocol.java | 2 +- .../java/org/traccar/protocol/WliProtocol.java | 2 +- .../java/org/traccar/protocol/WondexProtocol.java | 2 +- .../org/traccar/protocol/WristbandProtocol.java | 2 +- .../java/org/traccar/protocol/Xexun2Protocol.java | 2 +- .../java/org/traccar/protocol/XexunProtocol.java | 2 +- .../java/org/traccar/protocol/XirgoProtocol.java | 2 +- .../java/org/traccar/protocol/Xrb28Protocol.java | 2 +- .../java/org/traccar/protocol/Xt013Protocol.java | 2 +- .../java/org/traccar/protocol/Xt2400Protocol.java | 2 +- .../java/org/traccar/protocol/YwtProtocol.java | 2 +- .../traccar/reports/CombinedReportProvider.java | 2 +- .../org/traccar/reports/CsvExportProvider.java | 2 +- .../org/traccar/reports/EventsReportProvider.java | 2 +- .../org/traccar/reports/GpxExportProvider.java | 2 +- .../org/traccar/reports/KmlExportProvider.java | 2 +- .../org/traccar/reports/RouteReportProvider.java | 2 +- .../org/traccar/reports/StopsReportProvider.java | 2 +- .../org/traccar/reports/SummaryReportProvider.java | 2 +- .../org/traccar/reports/TripsReportProvider.java | 2 +- .../org/traccar/reports/common/ReportMailer.java | 10 ++--- .../org/traccar/reports/common/ReportUtils.java | 4 +- .../java/org/traccar/schedule/ScheduleManager.java | 4 +- .../schedule/TaskDeviceInactivityCheck.java | 2 +- .../java/org/traccar/schedule/TaskHealthCheck.java | 4 +- .../java/org/traccar/schedule/TaskReports.java | 2 +- .../traccar/schedule/TaskWebSocketKeepalive.java | 2 +- .../org/traccar/session/ConnectionManager.java | 4 +- .../org/traccar/session/cache/CacheManager.java | 4 +- src/main/java/org/traccar/sms/HttpSmsClient.java | 10 ++--- .../speedlimit/OverpassSpeedLimitProvider.java | 10 ++--- .../java/org/traccar/storage/DatabaseModule.java | 2 +- .../java/org/traccar/storage/DatabaseStorage.java | 2 +- src/main/java/org/traccar/web/ConsoleServlet.java | 8 ++-- .../java/org/traccar/web/ModernDefaultServlet.java | 2 +- src/main/java/org/traccar/web/OverrideFilter.java | 18 ++++---- src/main/java/org/traccar/web/ResponseWrapper.java | 8 ++-- .../java/org/traccar/web/ThrottlingFilter.java | 14 +++--- .../traccar/web/WebInjectionManagerFactory.java | 2 +- src/main/java/org/traccar/web/WebServer.java | 10 ++--- .../java/org/traccar/geocoder/GeocoderTest.java | 4 +- .../geolocation/GeolocationProviderTest.java | 4 +- .../java/org/traccar/helper/WebHelperTest.java | 2 +- .../notification/NotificiationMailTest.java | 10 ++--- .../speedlimit/OverpassSpeedLimitProviderTest.java | 4 +- 418 files changed, 835 insertions(+), 835 deletions(-) (limited to 'src/main/java/org') diff --git a/build.gradle b/build.gradle index d08dfebc5..06516794c 100644 --- a/build.gradle +++ b/build.gradle @@ -26,13 +26,13 @@ enforce { } ext { - guiceVersion = "6.0.0" - jettyVersion = "10.0.15" // jetty 11 javax to jakarta - jerseyVersion = "2.39.1" // jersey 3 javax to jakarta - jacksonVersion = "2.14.1" // same version as jersey-media-json-jackson dependency - protobufVersion = "3.23.2" - jxlsVersion = "2.12.0" - junitVersion = "5.9.3" + guiceVersion = "7.0.0" + jettyVersion = "11.0.15" + jerseyVersion = "3.1.3" + jacksonVersion = "2.15.2" // same version as jersey-media-json-jackson dependency + protobufVersion = "3.24.0" + jxlsVersion = "2.13.0" + junitVersion = "5.10.0" } protobuf { @@ -42,19 +42,20 @@ protobuf { } dependencies { - implementation "commons-codec:commons-codec:1.15" - implementation "com.h2database:h2:2.1.214" - implementation "com.mysql:mysql-connector-j:8.0.33" + implementation "commons-codec:commons-codec:1.16.0" + implementation "com.h2database:h2:2.2.220" + implementation "com.mysql:mysql-connector-j:8.1.0" implementation "org.mariadb.jdbc:mariadb-java-client:3.1.4" implementation "org.postgresql:postgresql:42.6.0" - implementation "com.microsoft.sqlserver:mssql-jdbc:12.2.0.jre11" + implementation "com.microsoft.sqlserver:mssql-jdbc:12.4.0.jre11" implementation "com.zaxxer:HikariCP:5.0.1" - implementation "io.netty:netty-all:4.1.93.Final" + implementation "io.netty:netty-all:4.1.96.Final" implementation "org.slf4j:slf4j-jdk14:2.0.7" implementation "com.google.inject:guice:$guiceVersion" implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" - implementation "org.glassfish:jakarta.json:1.1.6" + implementation "org.glassfish:jakarta.json:2.0.1" + implementation "com.sun.mail:jakarta.mail:2.0.1" implementation "org.eclipse.jetty:jetty-server:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlet:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlets:$jettyVersion" @@ -65,34 +66,33 @@ dependencies { implementation "org.glassfish.jersey.containers:jersey-container-servlet:$jerseyVersion" implementation "org.glassfish.jersey.media:jersey-media-json-jackson:$jerseyVersion" implementation "org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion" - implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 + implementation "org.glassfish.hk2:guice-bridge:3.0.4" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" - implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" - implementation "org.liquibase:liquibase-core:4.22.0" - implementation "com.sun.mail:jakarta.mail:1.6.7" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp:$jacksonVersion" + implementation "org.liquibase:liquibase-core:4.23.1" implementation "org.apache.commons:commons-jexl3:3.3" implementation "org.jxls:jxls:$jxlsVersion" implementation "org.jxls:jxls-poi:$jxlsVersion" implementation "org.apache.velocity:velocity-engine-core:2.3" implementation "org.apache.velocity.tools:velocity-tools-generic:3.1" implementation "org.apache.commons:commons-collections4:4.4" - implementation "org.mnode.ical4j:ical4j:3.2.11" + implementation "org.mnode.ical4j:ical4j:3.2.12" implementation "org.locationtech.spatial4j:spatial4j:0.8" implementation "org.locationtech.jts:jts-core:1.19.0" implementation "net.java.dev.jna:jna-platform:5.13.0" - implementation "com.github.jnr:jnr-posix:3.1.16" + implementation "com.github.jnr:jnr-posix:3.1.17" implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "javax.activation:activation:1.1.1" - implementation "com.amazonaws:aws-java-sdk-sns:1.12.477" - implementation "org.apache.kafka:kafka-clients:3.4.0" + implementation "com.amazonaws:aws-java-sdk-sns:1.12.532" + implementation "org.apache.kafka:kafka-clients:3.5.1" implementation "com.hivemq:hivemq-mqtt-client:1.3.1" - implementation "redis.clients:jedis:4.4.1" - implementation "com.google.firebase:firebase-admin:9.1.1" - implementation "com.nimbusds:oauth2-oidc-sdk:10.9.1" + implementation "redis.clients:jedis:4.4.3" + implementation "com.google.firebase:firebase-admin:9.2.0" + implementation "com.nimbusds:oauth2-oidc-sdk:10.13.2" implementation "com.rabbitmq:amqp-client:5.18.0" testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" testImplementation "org.junit.jupiter:junit-jupiter-engine:$junitVersion" - testImplementation "org.mockito:mockito-core:5.3.1" + testImplementation "org.mockito:mockito-core:5.4.0" } test { diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index 1948becc0..ea302997c 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.java @@ -23,8 +23,8 @@ import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.sms.SmsManager; -import javax.annotation.Nullable; -import javax.inject.Inject; +import jakarta.annotation.Nullable; +import jakarta.inject.Inject; import java.net.SocketAddress; import java.util.Arrays; import java.util.Collection; diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 382daf92f..69ca0ccc6 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -31,7 +31,7 @@ import org.traccar.session.DeviceSession; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Collection; diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 96de3e3f0..b9ca16838 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -27,7 +27,7 @@ import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; +import jakarta.inject.Inject; public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { diff --git a/src/main/java/org/traccar/ExtendedObjectDecoder.java b/src/main/java/org/traccar/ExtendedObjectDecoder.java index 805f98cb7..cddddcd80 100644 --- a/src/main/java/org/traccar/ExtendedObjectDecoder.java +++ b/src/main/java/org/traccar/ExtendedObjectDecoder.java @@ -27,7 +27,7 @@ import org.traccar.handler.AcknowledgementHandler; import org.traccar.helper.DataConverter; import org.traccar.model.Position; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 658ff6d6d..fb0171d63 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -41,8 +41,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f5db75846..6ed240d2c 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -17,7 +17,7 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr353.JSR353Module; +import com.fasterxml.jackson.datatype.jsonp.JSONPModule; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Provides; @@ -93,10 +93,10 @@ import org.traccar.storage.Storage; import org.traccar.web.WebServer; import org.traccar.api.security.LoginService; -import javax.annotation.Nullable; -import javax.inject.Singleton; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; +import jakarta.annotation.Nullable; +import jakarta.inject.Singleton; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; import java.io.IOException; import java.net.URISyntaxException; import java.net.http.HttpClient; @@ -134,7 +134,7 @@ public class MainModule extends AbstractModule { if (config.getBoolean(Keys.WEB_SANITIZE)) { objectMapper.registerModule(new SanitizerModule()); } - objectMapper.registerModule(new JSR353Module()); + objectMapper.registerModule(new JSONPModule()); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return objectMapper; } diff --git a/src/main/java/org/traccar/PositionForwardingHandler.java b/src/main/java/org/traccar/PositionForwardingHandler.java index 83f91e937..a79b01367 100644 --- a/src/main/java/org/traccar/PositionForwardingHandler.java +++ b/src/main/java/org/traccar/PositionForwardingHandler.java @@ -30,9 +30,9 @@ import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.annotation.Nullable; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 57afb01fd..e91be50a2 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -22,8 +22,8 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.ClassScanner; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.IOException; import java.net.BindException; import java.net.ConnectException; diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 91a745eeb..cd2c1639e 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -24,9 +24,9 @@ import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; import org.traccar.storage.Storage; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.servlet.http.HttpSession; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.servlet.http.HttpSession; import java.time.Duration; @Singleton diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index b007b7bcd..2aaed2bb5 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -29,14 +29,14 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.Response; +import jakarta.inject.Inject; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.core.Response; public abstract class BaseObjectResource extends BaseResource { diff --git a/src/main/java/org/traccar/api/BaseResource.java b/src/main/java/org/traccar/api/BaseResource.java index 33abe73fa..f20b8c4c2 100644 --- a/src/main/java/org/traccar/api/BaseResource.java +++ b/src/main/java/org/traccar/api/BaseResource.java @@ -19,9 +19,9 @@ import org.traccar.api.security.PermissionsService; import org.traccar.api.security.UserPrincipal; import org.traccar.storage.Storage; -import javax.inject.Inject; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.SecurityContext; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.SecurityContext; public class BaseResource { diff --git a/src/main/java/org/traccar/api/CorsResponseFilter.java b/src/main/java/org/traccar/api/CorsResponseFilter.java index 67d0341a1..a380eb41d 100644 --- a/src/main/java/org/traccar/api/CorsResponseFilter.java +++ b/src/main/java/org/traccar/api/CorsResponseFilter.java @@ -19,11 +19,11 @@ import io.netty.handler.codec.http.HttpHeaderNames; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerResponseContext; -import javax.ws.rs.container.ContainerResponseFilter; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerResponseContext; +import jakarta.ws.rs.container.ContainerResponseFilter; import java.io.IOException; @Singleton diff --git a/src/main/java/org/traccar/api/DateParameterConverterProvider.java b/src/main/java/org/traccar/api/DateParameterConverterProvider.java index f07ece984..4858fcbfd 100644 --- a/src/main/java/org/traccar/api/DateParameterConverterProvider.java +++ b/src/main/java/org/traccar/api/DateParameterConverterProvider.java @@ -17,8 +17,8 @@ package org.traccar.api; import org.traccar.helper.DateUtil; -import javax.ws.rs.ext.ParamConverter; -import javax.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Date; diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 8467b46c6..348ebe38a 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -25,8 +25,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.ws.rs.GET; -import javax.ws.rs.QueryParam; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.QueryParam; import java.util.Collection; import java.util.LinkedList; diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index e6556189a..38d13078d 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -28,16 +28,16 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.IOException; @Singleton diff --git a/src/main/java/org/traccar/api/ResourceErrorHandler.java b/src/main/java/org/traccar/api/ResourceErrorHandler.java index 108a8e8cc..387f3db6a 100644 --- a/src/main/java/org/traccar/api/ResourceErrorHandler.java +++ b/src/main/java/org/traccar/api/ResourceErrorHandler.java @@ -17,9 +17,9 @@ package org.traccar.api; import org.traccar.helper.Log; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.ExceptionMapper; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.ExceptionMapper; public class ResourceErrorHandler implements ExceptionMapper { diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index 4a435ca7d..c9d41b063 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -23,8 +23,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.ws.rs.GET; -import javax.ws.rs.QueryParam; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.QueryParam; import java.util.Collection; import java.util.LinkedList; diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index f85e90133..44f0ef452 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -16,17 +16,17 @@ */ package org.traccar.api.resource; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Attribute; diff --git a/src/main/java/org/traccar/api/resource/CalendarResource.java b/src/main/java/org/traccar/api/resource/CalendarResource.java index 9399c34a5..f6c1f3c59 100644 --- a/src/main/java/org/traccar/api/resource/CalendarResource.java +++ b/src/main/java/org/traccar/api/resource/CalendarResource.java @@ -16,10 +16,10 @@ */ package org.traccar.api.resource; -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; import org.traccar.api.SimpleObjectResource; import org.traccar.model.Calendar; diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 3df2244d1..d50c7ee0c 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -37,15 +37,15 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index c0b0cea0d..61a70bac0 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -30,19 +30,19 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.HeaderParam; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.io.File; import java.io.FileInputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/api/resource/DriverResource.java b/src/main/java/org/traccar/api/resource/DriverResource.java index 91aa54c5e..19cf74f39 100644 --- a/src/main/java/org/traccar/api/resource/DriverResource.java +++ b/src/main/java/org/traccar/api/resource/DriverResource.java @@ -16,10 +16,10 @@ */ package org.traccar.api.resource; -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Driver; diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index afdaf52b5..1f20b880d 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -23,14 +23,14 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; @Path("events") @Produces(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/traccar/api/resource/GeofenceResource.java b/src/main/java/org/traccar/api/resource/GeofenceResource.java index 58f2c188c..030690889 100644 --- a/src/main/java/org/traccar/api/resource/GeofenceResource.java +++ b/src/main/java/org/traccar/api/resource/GeofenceResource.java @@ -18,10 +18,10 @@ package org.traccar.api.resource; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Geofence; -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; @Path("geofences") @Produces(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/traccar/api/resource/GroupResource.java b/src/main/java/org/traccar/api/resource/GroupResource.java index fcea15d0a..628f8f655 100644 --- a/src/main/java/org/traccar/api/resource/GroupResource.java +++ b/src/main/java/org/traccar/api/resource/GroupResource.java @@ -18,10 +18,10 @@ package org.traccar.api.resource; import org.traccar.api.SimpleObjectResource; import org.traccar.model.Group; -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; @Path("groups") @Produces(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/traccar/api/resource/MaintenanceResource.java b/src/main/java/org/traccar/api/resource/MaintenanceResource.java index fa1b359ce..12841e497 100644 --- a/src/main/java/org/traccar/api/resource/MaintenanceResource.java +++ b/src/main/java/org/traccar/api/resource/MaintenanceResource.java @@ -16,10 +16,10 @@ */ package org.traccar.api.resource; -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Maintenance; diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 7005fc083..2a209efb6 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -26,15 +26,15 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.storage.StorageException; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; diff --git a/src/main/java/org/traccar/api/resource/OrderResource.java b/src/main/java/org/traccar/api/resource/OrderResource.java index 77608a508..3852b975f 100644 --- a/src/main/java/org/traccar/api/resource/OrderResource.java +++ b/src/main/java/org/traccar/api/resource/OrderResource.java @@ -18,10 +18,10 @@ package org.traccar.api.resource; import org.traccar.api.SimpleObjectResource; import org.traccar.model.Order; -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; @Path("orders") @Produces(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 67c9cee97..029e63a0c 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -25,16 +25,16 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.mail.MessagingException; -import javax.ws.rs.Consumes; -import javax.ws.rs.FormParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.annotation.security.PermitAll; +import jakarta.inject.Inject; +import jakarta.mail.MessagingException; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.FormParam; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.io.IOException; import java.security.GeneralSecurityException; diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index f02c5d426..e8e4e96eb 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -23,15 +23,15 @@ import org.traccar.model.UserRestrictions; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 37696a620..0d783a0fe 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -28,18 +28,18 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.DELETE; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.StreamingOutput; import java.util.ArrayList; import java.util.Collection; import java.util.Date; diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index e392f3f90..b4882f219 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -36,18 +36,18 @@ import org.traccar.reports.model.SummaryReportItem; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.StorageException; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.StreamingOutput; import java.util.Collection; import java.util.Date; import java.util.List; diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index dcb059b69..8149ec3b8 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -33,19 +33,19 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.annotation.Nullable; -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.annotation.Nullable; +import jakarta.annotation.security.PermitAll; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 9b6a74ddb..3e738c15a 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -29,24 +29,24 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import com.nimbusds.oauth2.sdk.ParseException; -import javax.annotation.Nullable; -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.annotation.Nullable; +import jakarta.annotation.security.PermitAll; +import jakarta.inject.Inject; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.FormParam; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/api/resource/StatisticsResource.java b/src/main/java/org/traccar/api/resource/StatisticsResource.java index 1f2296f28..0c728c77d 100644 --- a/src/main/java/org/traccar/api/resource/StatisticsResource.java +++ b/src/main/java/org/traccar/api/resource/StatisticsResource.java @@ -23,12 +23,12 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; import java.util.Collection; import java.util.Date; diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 19d88782f..cbee3bd4a 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -27,16 +27,16 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.annotation.security.PermitAll; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.util.Collection; @Path("users") diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index db9ed6cff..91e964ee9 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -27,9 +27,9 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.annotation.Nullable; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.IOException; import java.security.GeneralSecurityException; diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 7f5a46225..d60bbafb8 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -34,7 +34,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.Objects; @RequestScoped diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index e6641548a..a34361854 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -24,16 +24,16 @@ import org.traccar.helper.DataConverter; import org.traccar.model.User; import org.traccar.storage.StorageException; -import javax.annotation.security.PermitAll; -import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.container.ResourceInfo; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.SecurityContext; +import jakarta.annotation.security.PermitAll; +import jakarta.inject.Inject; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.container.ResourceInfo; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; import java.io.IOException; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/api/security/UserSecurityContext.java b/src/main/java/org/traccar/api/security/UserSecurityContext.java index 97df6b6c7..f7adeac64 100644 --- a/src/main/java/org/traccar/api/security/UserSecurityContext.java +++ b/src/main/java/org/traccar/api/security/UserSecurityContext.java @@ -15,7 +15,7 @@ */ package org.traccar.api.security; -import javax.ws.rs.core.SecurityContext; +import jakarta.ws.rs.core.SecurityContext; import java.security.Principal; public class UserSecurityContext implements SecurityContext { diff --git a/src/main/java/org/traccar/api/signature/CryptoManager.java b/src/main/java/org/traccar/api/signature/CryptoManager.java index 249d5bd97..71f56e0fb 100644 --- a/src/main/java/org/traccar/api/signature/CryptoManager.java +++ b/src/main/java/org/traccar/api/signature/CryptoManager.java @@ -20,8 +20,8 @@ import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.KeyPair; diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java index 6a0d90b40..3019e12b9 100644 --- a/src/main/java/org/traccar/api/signature/TokenManager.java +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -20,8 +20,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.codec.binary.Base64; import org.traccar.storage.StorageException; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Date; diff --git a/src/main/java/org/traccar/config/Config.java b/src/main/java/org/traccar/config/Config.java index c73be6475..47e1f0707 100644 --- a/src/main/java/org/traccar/config/Config.java +++ b/src/main/java/org/traccar/config/Config.java @@ -19,8 +19,8 @@ import com.google.common.annotations.VisibleForTesting; import com.google.inject.name.Named; import org.traccar.helper.Log; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index df399cd7a..fb8f2f9d6 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -34,9 +34,9 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.annotation.Nullable; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Collection; import java.util.stream.Collectors; diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index 583b2ae35..6ec6841a1 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -29,8 +29,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/org/traccar/database/MediaManager.java b/src/main/java/org/traccar/database/MediaManager.java index c1ef810ee..2f2369c96 100644 --- a/src/main/java/org/traccar/database/MediaManager.java +++ b/src/main/java/org/traccar/database/MediaManager.java @@ -21,8 +21,8 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 32216dfc6..3a57788fb 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -38,9 +38,9 @@ import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.annotation.Nullable; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Arrays; import java.util.Map; import java.util.Map.Entry; diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index d0ec4e98d..312be8890 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -33,7 +33,7 @@ import java.security.GeneralSecurityException; import java.util.List; import java.util.Map; import java.io.IOException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index 0e9931fba..445e53e7c 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -29,11 +29,11 @@ import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.Form; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.core.Form; import java.util.Calendar; import java.util.Date; import java.util.HashMap; diff --git a/src/main/java/org/traccar/forward/EventForwarderJson.java b/src/main/java/org/traccar/forward/EventForwarderJson.java index 7527d568a..df53d3d46 100644 --- a/src/main/java/org/traccar/forward/EventForwarderJson.java +++ b/src/main/java/org/traccar/forward/EventForwarderJson.java @@ -18,10 +18,10 @@ package org.traccar.forward; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; -import javax.ws.rs.core.Response; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.InvocationCallback; +import jakarta.ws.rs.core.Response; public class EventForwarderJson implements EventForwarder { diff --git a/src/main/java/org/traccar/forward/NetworkForwarder.java b/src/main/java/org/traccar/forward/NetworkForwarder.java index 0915aaa27..86c9a77f3 100644 --- a/src/main/java/org/traccar/forward/NetworkForwarder.java +++ b/src/main/java/org/traccar/forward/NetworkForwarder.java @@ -20,8 +20,8 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; diff --git a/src/main/java/org/traccar/forward/PositionForwarderJson.java b/src/main/java/org/traccar/forward/PositionForwarderJson.java index 27b96308e..a0ad8ffd0 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderJson.java +++ b/src/main/java/org/traccar/forward/PositionForwarderJson.java @@ -20,12 +20,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.InvocationCallback; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; public class PositionForwarderJson implements PositionForwarder { diff --git a/src/main/java/org/traccar/forward/PositionForwarderUrl.java b/src/main/java/org/traccar/forward/PositionForwarderUrl.java index 53cc7ad24..33474d40b 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderUrl.java +++ b/src/main/java/org/traccar/forward/PositionForwarderUrl.java @@ -23,9 +23,9 @@ import org.traccar.helper.Checksum; import org.traccar.model.Device; import org.traccar.model.Position; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.InvocationCallback; -import javax.ws.rs.core.Response; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.InvocationCallback; +import jakarta.ws.rs.core.Response; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/geocoder/BanGeocoder.java b/src/main/java/org/traccar/geocoder/BanGeocoder.java index f878a8bab..e2ff72311 100644 --- a/src/main/java/org/traccar/geocoder/BanGeocoder.java +++ b/src/main/java/org/traccar/geocoder/BanGeocoder.java @@ -20,9 +20,9 @@ package org.traccar.geocoder; * API documentation: https://adresse.data.gouv.fr/api */ -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class BanGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java b/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java index 01e33c2ea..bc3b15ce7 100644 --- a/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java +++ b/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java @@ -16,9 +16,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class BingMapsGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/FactualGeocoder.java b/src/main/java/org/traccar/geocoder/FactualGeocoder.java index 384f46b0e..6c8891316 100644 --- a/src/main/java/org/traccar/geocoder/FactualGeocoder.java +++ b/src/main/java/org/traccar/geocoder/FactualGeocoder.java @@ -16,8 +16,8 @@ */ package org.traccar.geocoder; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class FactualGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java index 4748d6a2c..35a47bb88 100644 --- a/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java @@ -15,9 +15,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class GeoapifyGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java b/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java index 2af95910f..80b00b3cc 100644 --- a/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java @@ -15,8 +15,8 @@ */ package org.traccar.geocoder; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class GeocodeFarmGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java b/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java index 96491ece3..e88962e1a 100644 --- a/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java @@ -15,8 +15,8 @@ */ package org.traccar.geocoder; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class GeocodeXyzGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java b/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java index 0589eb000..062e795eb 100644 --- a/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java @@ -15,8 +15,8 @@ */ package org.traccar.geocoder; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class GisgraphyGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java index 4d9ec8f36..93f128b46 100644 --- a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java @@ -15,10 +15,10 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonString; +import jakarta.ws.rs.client.Client; public class GoogleGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/HereGeocoder.java b/src/main/java/org/traccar/geocoder/HereGeocoder.java index eb639995e..2d1bc1bf4 100644 --- a/src/main/java/org/traccar/geocoder/HereGeocoder.java +++ b/src/main/java/org/traccar/geocoder/HereGeocoder.java @@ -15,8 +15,8 @@ */ package org.traccar.geocoder; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class HereGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/JsonGeocoder.java b/src/main/java/org/traccar/geocoder/JsonGeocoder.java index 6105e8cfd..f9b039f43 100644 --- a/src/main/java/org/traccar/geocoder/JsonGeocoder.java +++ b/src/main/java/org/traccar/geocoder/JsonGeocoder.java @@ -19,10 +19,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.database.StatisticsManager; -import javax.json.JsonObject; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.InvocationCallback; +import jakarta.json.JsonObject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.InvocationCallback; import java.util.AbstractMap; import java.util.Collections; import java.util.LinkedHashMap; diff --git a/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java b/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java index f2ffe02d6..f304ffeff 100644 --- a/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java +++ b/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java @@ -15,7 +15,7 @@ */ package org.traccar.geocoder; -import javax.ws.rs.client.Client; +import jakarta.ws.rs.client.Client; public class LocationIqGeocoder extends NominatimGeocoder { diff --git a/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java b/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java index 3f2554c6e..1b6c8adcc 100644 --- a/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java @@ -16,9 +16,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class MapQuestGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java index 203f5f99b..24c9da2ad 100644 --- a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java @@ -15,9 +15,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class MapTilerGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/MapboxGeocoder.java b/src/main/java/org/traccar/geocoder/MapboxGeocoder.java index 72bfb53f5..9fa6b8d88 100644 --- a/src/main/java/org/traccar/geocoder/MapboxGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapboxGeocoder.java @@ -15,10 +15,10 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonString; +import jakarta.ws.rs.client.Client; public class MapboxGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java b/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java index dea295cca..b68db07bc 100644 --- a/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java @@ -15,9 +15,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class MapmyIndiaGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/NominatimGeocoder.java b/src/main/java/org/traccar/geocoder/NominatimGeocoder.java index b731549f7..1e26d0042 100644 --- a/src/main/java/org/traccar/geocoder/NominatimGeocoder.java +++ b/src/main/java/org/traccar/geocoder/NominatimGeocoder.java @@ -15,8 +15,8 @@ */ package org.traccar.geocoder; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class NominatimGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java index fb61440aa..4607fdc87 100644 --- a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java +++ b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java @@ -16,9 +16,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class OpenCageGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java b/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java index 9778d9eda..4aed27fc5 100644 --- a/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java +++ b/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java @@ -15,9 +15,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class PositionStackGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geocoder/TomTomGeocoder.java b/src/main/java/org/traccar/geocoder/TomTomGeocoder.java index 9bb36efc2..4d452fd43 100644 --- a/src/main/java/org/traccar/geocoder/TomTomGeocoder.java +++ b/src/main/java/org/traccar/geocoder/TomTomGeocoder.java @@ -15,9 +15,9 @@ */ package org.traccar.geocoder; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; public class TomTomGeocoder extends JsonGeocoder { diff --git a/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java b/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java index 8f0f3b704..9425e9111 100644 --- a/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java @@ -15,7 +15,7 @@ */ package org.traccar.geolocation; -import javax.ws.rs.client.Client; +import jakarta.ws.rs.client.Client; public class GoogleGeolocationProvider extends UniversalGeolocationProvider { diff --git a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java b/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java index 3b4ba4e1f..7eb22dcca 100644 --- a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java @@ -15,7 +15,7 @@ */ package org.traccar.geolocation; -import javax.ws.rs.client.Client; +import jakarta.ws.rs.client.Client; public class MozillaGeolocationProvider extends UniversalGeolocationProvider { diff --git a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index 82fcf42ab..72a05d10f 100644 --- a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java @@ -18,9 +18,9 @@ package org.traccar.geolocation; import org.traccar.model.CellTower; import org.traccar.model.Network; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.InvocationCallback; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.InvocationCallback; public class OpenCellIdGeolocationProvider implements GeolocationProvider { diff --git a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java index 7a3f71ee1..9086d8ce3 100644 --- a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java @@ -17,10 +17,10 @@ package org.traccar.geolocation; import org.traccar.model.Network; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.InvocationCallback; public class UniversalGeolocationProvider implements GeolocationProvider { diff --git a/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java index 14893b6a3..4f1c5617e 100644 --- a/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java @@ -23,10 +23,10 @@ import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.WifiAccessPoint; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.InvocationCallback; import java.util.Collection; public class UnwiredGeolocationProvider implements GeolocationProvider { diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 8ad4e41e4..042747359 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -43,8 +43,8 @@ import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index e5c9bc29a..42b438e41 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -24,8 +24,8 @@ import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java index 89255a5fe..cca6dcd0a 100644 --- a/src/main/java/org/traccar/handler/DefaultDataHandler.java +++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java @@ -24,8 +24,8 @@ import org.traccar.storage.Storage; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index 30dc9ff2b..7fdefa1f4 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -24,8 +24,8 @@ import org.traccar.helper.DistanceCalculator; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.math.BigDecimal; import java.math.RoundingMode; diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index c10fe9064..621205b34 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -21,8 +21,8 @@ import org.traccar.BaseDataHandler; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 028e4cd09..a15d3ffad 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -36,8 +36,8 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Date; @Singleton diff --git a/src/main/java/org/traccar/handler/GeofenceHandler.java b/src/main/java/org/traccar/handler/GeofenceHandler.java index fe15cef8e..68bc6dbf0 100644 --- a/src/main/java/org/traccar/handler/GeofenceHandler.java +++ b/src/main/java/org/traccar/handler/GeofenceHandler.java @@ -22,8 +22,8 @@ import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.List; @Singleton diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java index ccbde9fe5..294e449db 100644 --- a/src/main/java/org/traccar/handler/HemisphereHandler.java +++ b/src/main/java/org/traccar/handler/HemisphereHandler.java @@ -21,8 +21,8 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 297527b4d..68a31a16a 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -23,8 +23,8 @@ import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/NetworkForwarderHandler.java b/src/main/java/org/traccar/handler/NetworkForwarderHandler.java index 2c586c973..470e175ca 100644 --- a/src/main/java/org/traccar/handler/NetworkForwarderHandler.java +++ b/src/main/java/org/traccar/handler/NetworkForwarderHandler.java @@ -22,7 +22,7 @@ import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.DatagramPacket; import org.traccar.forward.NetworkForwarder; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.InetSocketAddress; import java.net.SocketAddress; diff --git a/src/main/java/org/traccar/handler/RemoteAddressHandler.java b/src/main/java/org/traccar/handler/RemoteAddressHandler.java index e18d34ef2..61ada5b91 100644 --- a/src/main/java/org/traccar/handler/RemoteAddressHandler.java +++ b/src/main/java/org/traccar/handler/RemoteAddressHandler.java @@ -22,8 +22,8 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.net.InetSocketAddress; @Singleton diff --git a/src/main/java/org/traccar/handler/SpeedLimitHandler.java b/src/main/java/org/traccar/handler/SpeedLimitHandler.java index 0c6025999..6edb6e912 100644 --- a/src/main/java/org/traccar/handler/SpeedLimitHandler.java +++ b/src/main/java/org/traccar/handler/SpeedLimitHandler.java @@ -23,8 +23,8 @@ import org.slf4j.LoggerFactory; import org.traccar.model.Position; import org.traccar.speedlimit.SpeedLimitProvider; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java index c98b0bd4c..3c3e17450 100644 --- a/src/main/java/org/traccar/handler/TimeHandler.java +++ b/src/main/java/org/traccar/handler/TimeHandler.java @@ -23,8 +23,8 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java index 9f77df989..531a0f957 100644 --- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -25,8 +25,8 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/events/BaseEventHandler.java b/src/main/java/org/traccar/handler/events/BaseEventHandler.java index 271aaa35d..4a4fb40ff 100644 --- a/src/main/java/org/traccar/handler/events/BaseEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BaseEventHandler.java @@ -22,7 +22,7 @@ import org.traccar.database.NotificationManager; import org.traccar.model.Event; import org.traccar.model.Position; -import javax.inject.Inject; +import jakarta.inject.Inject; public abstract class BaseEventHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java index 51bbd82d6..08ae35fcd 100644 --- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java @@ -23,8 +23,8 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Collections; import java.util.Map; diff --git a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java index 772176e9c..b70f8f33b 100644 --- a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java +++ b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java @@ -22,8 +22,8 @@ import io.netty.channel.ChannelHandler; import org.traccar.model.Event; import org.traccar.model.Position; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java index 51fdc0307..b68327983 100644 --- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -22,8 +22,8 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Collections; import java.util.Map; diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java index a1584d4e4..e5085ecc2 100644 --- a/src/main/java/org/traccar/handler/events/FuelEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -24,8 +24,8 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Map; @Singleton diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 096f71373..dbe2b8118 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -23,8 +23,8 @@ import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index b2e9a3325..ba4159a42 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -26,8 +26,8 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 909950acf..6c4271ce2 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -25,8 +25,8 @@ import org.traccar.model.Maintenance; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton @ChannelHandler.Sharable diff --git a/src/main/java/org/traccar/handler/events/MediaEventHandler.java b/src/main/java/org/traccar/handler/events/MediaEventHandler.java index a49e08e8d..52d8e6961 100644 --- a/src/main/java/org/traccar/handler/events/MediaEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MediaEventHandler.java @@ -19,8 +19,8 @@ import io.netty.channel.ChannelHandler; import org.traccar.model.Event; import org.traccar.model.Position; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index d2c54ccf3..15902d6d4 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -35,8 +35,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Collections; import java.util.Map; diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 40f1c7442..94fdc4699 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -36,8 +36,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Collections; import java.util.Map; diff --git a/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java b/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java index b40e30d76..634950b85 100644 --- a/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java +++ b/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java @@ -17,8 +17,8 @@ package org.traccar.helper; import com.fasterxml.jackson.databind.ObjectMapper; -import javax.inject.Inject; -import javax.ws.rs.ext.ContextResolver; +import jakarta.inject.Inject; +import jakarta.ws.rs.ext.ContextResolver; // This does not work as a lambda public class ObjectMapperContextResolver implements ContextResolver { diff --git a/src/main/java/org/traccar/helper/WebHelper.java b/src/main/java/org/traccar/helper/WebHelper.java index e2844bc4d..9533fe84b 100644 --- a/src/main/java/org/traccar/helper/WebHelper.java +++ b/src/main/java/org/traccar/helper/WebHelper.java @@ -18,7 +18,7 @@ package org.traccar.helper; import java.net.InetAddress; import java.net.UnknownHostException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.eclipse.jetty.util.URIUtil; import org.traccar.config.Config; diff --git a/src/main/java/org/traccar/mail/LogMailManager.java b/src/main/java/org/traccar/mail/LogMailManager.java index 5c7572b0c..90de3bcce 100644 --- a/src/main/java/org/traccar/mail/LogMailManager.java +++ b/src/main/java/org/traccar/mail/LogMailManager.java @@ -19,8 +19,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.User; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeBodyPart; public class LogMailManager implements MailManager { diff --git a/src/main/java/org/traccar/mail/MailManager.java b/src/main/java/org/traccar/mail/MailManager.java index 3547fd37e..d05a07de9 100644 --- a/src/main/java/org/traccar/mail/MailManager.java +++ b/src/main/java/org/traccar/mail/MailManager.java @@ -17,8 +17,8 @@ package org.traccar.mail; import org.traccar.model.User; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeBodyPart; public interface MailManager { diff --git a/src/main/java/org/traccar/mail/SmtpMailManager.java b/src/main/java/org/traccar/mail/SmtpMailManager.java index 8d1afbd3e..70099d879 100644 --- a/src/main/java/org/traccar/mail/SmtpMailManager.java +++ b/src/main/java/org/traccar/mail/SmtpMailManager.java @@ -23,16 +23,16 @@ import org.traccar.database.StatisticsManager; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; -import javax.mail.BodyPart; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; +import jakarta.mail.BodyPart; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.Multipart; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 9ee3b97b6..85e8a54bb 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -27,8 +27,8 @@ import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.cache.CacheManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton public class NotificationFormatter { diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index b6ee760f3..8d41ee354 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -30,8 +30,8 @@ import org.traccar.notificators.NotificatorTelegram; import org.traccar.notificators.NotificatorTraccar; import org.traccar.notificators.NotificatorWeb; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.Map; diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 444f4a7c2..ab90d76d4 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -29,8 +29,8 @@ import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.StorageException; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/notificators/NotificatorCommand.java b/src/main/java/org/traccar/notificators/NotificatorCommand.java index 55cbe0a6a..5dd3313d4 100644 --- a/src/main/java/org/traccar/notificators/NotificatorCommand.java +++ b/src/main/java/org/traccar/notificators/NotificatorCommand.java @@ -27,8 +27,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton public class NotificatorCommand implements Notificator { diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index d80354d7d..be95fb28e 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -44,8 +44,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 8818a5a75..3ab050686 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -24,9 +24,9 @@ import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.mail.MessagingException; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.mail.MessagingException; @Singleton public class NotificatorMail implements Notificator { diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 703d86876..9f2a8c94d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -24,10 +24,10 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; @Singleton public class NotificatorPushover implements Notificator { diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 7ec47b156..2b6b20b1b 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -25,8 +25,8 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import org.traccar.sms.SmsManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton public class NotificatorSms implements Notificator { diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 63d2bb717..c91aaa4ff 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -25,10 +25,10 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; @Singleton public class NotificatorTelegram implements Notificator { diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index fb9632ad0..e354adccb 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -31,12 +31,12 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.json.JsonObject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.Response; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.core.Response; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 51884074e..3a125db3c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -23,8 +23,8 @@ import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import org.traccar.session.ConnectionManager; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; @Singleton public final class NotificatorWeb implements Notificator { diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java index bab1d2339..3856dc906 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocol.java +++ b/src/main/java/org/traccar/protocol/AdmProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AdmProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AisProtocol.java b/src/main/java/org/traccar/protocol/AisProtocol.java index bc975c277..e792a1d3f 100644 --- a/src/main/java/org/traccar/protocol/AisProtocol.java +++ b/src/main/java/org/traccar/protocol/AisProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AisProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocol.java b/src/main/java/org/traccar/protocol/AlematicsProtocol.java index b85b44382..5219607e7 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AlematicsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocol.java b/src/main/java/org/traccar/protocol/AnytrekProtocol.java index b0e974c69..5dce15ce1 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocol.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AnytrekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ApelProtocol.java b/src/main/java/org/traccar/protocol/ApelProtocol.java index f1d6e659c..550581b85 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocol.java +++ b/src/main/java/org/traccar/protocol/ApelProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ApelProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AplicomProtocol.java b/src/main/java/org/traccar/protocol/AplicomProtocol.java index 47bb780cb..48c628d22 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocol.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AplicomProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AppelloProtocol.java b/src/main/java/org/traccar/protocol/AppelloProtocol.java index 25b2bf3b8..34055d7e4 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocol.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AppelloProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AquilaProtocol.java b/src/main/java/org/traccar/protocol/AquilaProtocol.java index 6080df33d..bd9c34d08 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocol.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AquilaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Ardi01Protocol.java b/src/main/java/org/traccar/protocol/Ardi01Protocol.java index b33c2817f..5ddbe9d62 100644 --- a/src/main/java/org/traccar/protocol/Ardi01Protocol.java +++ b/src/main/java/org/traccar/protocol/Ardi01Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Ardi01Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index 4f443aa3a..20fec296c 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ArknavProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java index 39c6e8009..a8be6f40c 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java +++ b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ArknavX8Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 32fba3b52..e9c947ecd 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ArmoliProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocol.java b/src/main/java/org/traccar/protocol/ArnaviProtocol.java index 091d5c06f..962bcce52 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocol.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ArnaviProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java index 361eeeef2..50ceea898 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.SocketAddress; public class ArnaviProtocolDecoder extends BaseProtocolDecoder { diff --git a/src/main/java/org/traccar/protocol/AstraProtocol.java b/src/main/java/org/traccar/protocol/AstraProtocol.java index 021a81e07..dcc02d10d 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocol.java +++ b/src/main/java/org/traccar/protocol/AstraProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AstraProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/At2000Protocol.java b/src/main/java/org/traccar/protocol/At2000Protocol.java index 25e9be86f..c7e22f142 100644 --- a/src/main/java/org/traccar/protocol/At2000Protocol.java +++ b/src/main/java/org/traccar/protocol/At2000Protocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class At2000Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java index 21eb09696..8b86955f4 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AtrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AuroProtocol.java b/src/main/java/org/traccar/protocol/AuroProtocol.java index d37884c8b..728c8e23c 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocol.java +++ b/src/main/java/org/traccar/protocol/AuroProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AuroProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocol.java b/src/main/java/org/traccar/protocol/AustinNbProtocol.java index 6a68467e2..467deff53 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocol.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AustinNbProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocol.java b/src/main/java/org/traccar/protocol/AutoFonProtocol.java index 0566b1da6..75bd28d5e 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AutoFonProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java index bc80e473a..69d9fb4e6 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AutoGradeProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java index 80255d3e9..df489de3c 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AutoTrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/AvemaProtocol.java b/src/main/java/org/traccar/protocol/AvemaProtocol.java index b35a447ff..0eeee41b8 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocol.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class AvemaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Avl301Protocol.java b/src/main/java/org/traccar/protocol/Avl301Protocol.java index c4a0affdc..452bc1501 100644 --- a/src/main/java/org/traccar/protocol/Avl301Protocol.java +++ b/src/main/java/org/traccar/protocol/Avl301Protocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Avl301Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java index 582be0b56..e0a6821d8 100644 --- a/src/main/java/org/traccar/protocol/B2316Protocol.java +++ b/src/main/java/org/traccar/protocol/B2316Protocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class B2316Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java index 635806b2d..b0a5411f7 100644 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -24,9 +24,9 @@ import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.util.Date; diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java index 31fb1bd83..5e1c10abc 100644 --- a/src/main/java/org/traccar/protocol/BceProtocol.java +++ b/src/main/java/org/traccar/protocol/BceProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class BceProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java index 3859a9273..d584af5a1 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class BlackKiteProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/BlueProtocol.java b/src/main/java/org/traccar/protocol/BlueProtocol.java index da195f438..821111ad7 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocol.java +++ b/src/main/java/org/traccar/protocol/BlueProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class BlueProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/BoxProtocol.java b/src/main/java/org/traccar/protocol/BoxProtocol.java index dc6852d50..ac1ba7cae 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocol.java +++ b/src/main/java/org/traccar/protocol/BoxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class BoxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/BstplProtocol.java b/src/main/java/org/traccar/protocol/BstplProtocol.java index dde14a2ca..ccedcf3d9 100644 --- a/src/main/java/org/traccar/protocol/BstplProtocol.java +++ b/src/main/java/org/traccar/protocol/BstplProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class BstplProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/C2stekProtocol.java b/src/main/java/org/traccar/protocol/C2stekProtocol.java index 5cd8ef4fd..5370ea762 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocol.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class C2stekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocol.java b/src/main/java/org/traccar/protocol/CalAmpProtocol.java index d67308cf2..06df6e196 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocol.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CalAmpProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocol.java b/src/main/java/org/traccar/protocol/CarTrackProtocol.java index 0538aad72..366f32034 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CarTrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java index 832d9bb2d..7ae8159d5 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocol.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CarcellProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CarscopProtocol.java b/src/main/java/org/traccar/protocol/CarscopProtocol.java index a4413af28..e904c01c5 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocol.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CarscopProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java index 9323b1503..74a9e9ca1 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocol.java +++ b/src/main/java/org/traccar/protocol/CastelProtocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CastelProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CautelaProtocol.java b/src/main/java/org/traccar/protocol/CautelaProtocol.java index d0ca35ef1..067345f49 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocol.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CautelaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java index 3287928c7..e3325c8b7 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CellocatorProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CguardProtocol.java b/src/main/java/org/traccar/protocol/CguardProtocol.java index caf0aad42..c0fc9582a 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocol.java +++ b/src/main/java/org/traccar/protocol/CguardProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CguardProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java index 9656b284b..60ed5d135 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CityeasyProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocol.java b/src/main/java/org/traccar/protocol/ContinentalProtocol.java index 06e93d79d..9567374fd 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocol.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ContinentalProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocol.java b/src/main/java/org/traccar/protocol/CradlepointProtocol.java index 7f201a31d..220db0747 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocol.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class CradlepointProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/DingtekProtocol.java b/src/main/java/org/traccar/protocol/DingtekProtocol.java index e9466b7e8..ab3e32fdb 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocol.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class DingtekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/DishaProtocol.java b/src/main/java/org/traccar/protocol/DishaProtocol.java index f83b8349a..0a582731d 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocol.java +++ b/src/main/java/org/traccar/protocol/DishaProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class DishaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java index 0dab26cda..d15bfa1ca 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class DmtHttpProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 807850778..c2e617a2a 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -25,9 +25,9 @@ import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/DmtProtocol.java b/src/main/java/org/traccar/protocol/DmtProtocol.java index de56c9372..e89920cd3 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class DmtProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/DolphinProtocol.java b/src/main/java/org/traccar/protocol/DolphinProtocol.java index ed627be78..e2acce7dd 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocol.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class DolphinProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Dsf22Protocol.java b/src/main/java/org/traccar/protocol/Dsf22Protocol.java index 06c99b0f9..ad349a7ff 100644 --- a/src/main/java/org/traccar/protocol/Dsf22Protocol.java +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Dsf22Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java index 363a2c5d9..4725cb180 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class DualcamProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/DwayProtocol.java b/src/main/java/org/traccar/protocol/DwayProtocol.java index 1096c945c..2ba1cf5f1 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocol.java +++ b/src/main/java/org/traccar/protocol/DwayProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class DwayProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java index 39aa61580..25d4ef9a0 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EasyTrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java index 35fd4fe65..2a3c0bd15 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocol.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EelinkProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EgtsProtocol.java b/src/main/java/org/traccar/protocol/EgtsProtocol.java index f257271d4..5450d9f01 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocol.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EgtsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java index ebde56f70..3b796db25 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocol.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EnforaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocol.java b/src/main/java/org/traccar/protocol/EnnfuProtocol.java index e326481fa..a3ff943fa 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocol.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EnnfuProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocol.java b/src/main/java/org/traccar/protocol/EnvotechProtocol.java index dffa1c991..e432ac07c 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocol.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EnvotechProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java index 0ed80dc6f..eae4cf2aa 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocol.java +++ b/src/main/java/org/traccar/protocol/EsealProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EsealProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/EskyProtocol.java b/src/main/java/org/traccar/protocol/EskyProtocol.java index cb2f59dc8..002e268ba 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocol.java +++ b/src/main/java/org/traccar/protocol/EskyProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class EskyProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java index ffc941b69..23a993fe4 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ExtremTracProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java index fd2beaabb..e98ad84cc 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FifotrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FlespiProtocol.java b/src/main/java/org/traccar/protocol/FlespiProtocol.java index 374cf77e2..0d8448845 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FlespiProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 95d491af7..ea076afd8 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -24,12 +24,12 @@ import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonNumber; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.json.JsonValue; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonNumber; +import jakarta.json.JsonObject; +import jakarta.json.JsonString; +import jakarta.json.JsonValue; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index 088072d2d..b2e3f5d00 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -24,7 +24,7 @@ import org.traccar.config.Config; import java.nio.charset.StandardCharsets; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FlexApiProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index 2dec44e64..fb76673ca 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -23,8 +23,8 @@ import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.util.Date; diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocol.java b/src/main/java/org/traccar/protocol/FlexCommProtocol.java index 5397156cb..293b9b12b 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FlexCommProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java index 61e315af9..a16e61458 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FlexibleReportProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocol.java b/src/main/java/org/traccar/protocol/FlextrackProtocol.java index ebac8b4de..b6353de9d 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FlextrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FoxProtocol.java b/src/main/java/org/traccar/protocol/FoxProtocol.java index fa45b3817..edb496f11 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocol.java +++ b/src/main/java/org/traccar/protocol/FoxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FoxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FreedomProtocol.java b/src/main/java/org/traccar/protocol/FreedomProtocol.java index dac117c04..87404094a 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocol.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FreedomProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocol.java b/src/main/java/org/traccar/protocol/FreematicsProtocol.java index dce4994ab..c4076f330 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FreematicsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocol.java b/src/main/java/org/traccar/protocol/FutureWayProtocol.java index 715dd3c9c..20586bede 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocol.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class FutureWayProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/G1rusProtocol.java b/src/main/java/org/traccar/protocol/G1rusProtocol.java index f1823762d..b3904b357 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocol.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class G1rusProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java index 90e95574a..95ce4edde 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocol.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GalileoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index 46862f583..c961093ab 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GatorProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GenxProtocol.java b/src/main/java/org/traccar/protocol/GenxProtocol.java index 97d8633a0..7e5a6a69e 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocol.java +++ b/src/main/java/org/traccar/protocol/GenxProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GenxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gl100Protocol.java b/src/main/java/org/traccar/protocol/Gl100Protocol.java index e1748c9a0..fdd79648f 100644 --- a/src/main/java/org/traccar/protocol/Gl100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl100Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gl100Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java index c7b6a8e7c..e3ddbb46e 100644 --- a/src/main/java/org/traccar/protocol/Gl200Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gl200Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java index a9736c9e7..9b4e05c35 100644 --- a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.Protocol; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.SocketAddress; public class Gl200ProtocolDecoder extends BaseProtocolDecoder { diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java index 16b99f426..13f4f2646 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GlobalSatProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java index 293f5fda5..1d9b6b6dd 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GlobalstarProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GnxProtocol.java b/src/main/java/org/traccar/protocol/GnxProtocol.java index 32d642688..cfa496009 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocol.java +++ b/src/main/java/org/traccar/protocol/GnxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GnxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocol.java b/src/main/java/org/traccar/protocol/GoSafeProtocol.java index 607931500..c9c0456a0 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocol.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GoSafeProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GotopProtocol.java b/src/main/java/org/traccar/protocol/GotopProtocol.java index 53fcea0d0..21fbbae99 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocol.java +++ b/src/main/java/org/traccar/protocol/GotopProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GotopProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gps056Protocol.java b/src/main/java/org/traccar/protocol/Gps056Protocol.java index dbffbfdbb..44fc392be 100644 --- a/src/main/java/org/traccar/protocol/Gps056Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps056Protocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gps056Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java index 2725494c5..8424abfe5 100644 --- a/src/main/java/org/traccar/protocol/Gps103Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gps103Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocol.java b/src/main/java/org/traccar/protocol/GpsGateProtocol.java index a6a73ae6b..db1e8554a 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GpsGateProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java index 12b53342c..f50088b2b 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GpsMarkerProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java index a474b1e53..e146a816d 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GpsmtaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java index bb66501e2..9ca0fe25e 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocol.java +++ b/src/main/java/org/traccar/protocol/GranitProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class GranitProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gs100Protocol.java b/src/main/java/org/traccar/protocol/Gs100Protocol.java index 425ca9330..715d48fc4 100644 --- a/src/main/java/org/traccar/protocol/Gs100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gs100Protocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gs100Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gt02Protocol.java b/src/main/java/org/traccar/protocol/Gt02Protocol.java index fa05761f6..f448feacc 100644 --- a/src/main/java/org/traccar/protocol/Gt02Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt02Protocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gt02Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java index 38278121c..945ec3831 100644 --- a/src/main/java/org/traccar/protocol/Gt06Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gt06Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Gt30Protocol.java b/src/main/java/org/traccar/protocol/Gt30Protocol.java index 6b79ba58b..fdfc80502 100644 --- a/src/main/java/org/traccar/protocol/Gt30Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt30Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Gt30Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java index 4e5f8c96a..ba5aeaa26 100644 --- a/src/main/java/org/traccar/protocol/H02Protocol.java +++ b/src/main/java/org/traccar/protocol/H02Protocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class H02Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/HaicomProtocol.java b/src/main/java/org/traccar/protocol/HaicomProtocol.java index f56c605f0..bcc491ada 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocol.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class HaicomProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocol.java b/src/main/java/org/traccar/protocol/HomtecsProtocol.java index aa2d7d852..c04efb945 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocol.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class HomtecsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java index 02d8e5a8e..3fc0887d8 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class HoopoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java index 708c74f2a..7433e7fce 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -21,8 +21,8 @@ import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.time.OffsetDateTime; diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index 1f8bafc57..7246e97e6 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class HuaShengProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java index c37918b0e..fc12d7d71 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class HuabaoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/HunterProProtocol.java b/src/main/java/org/traccar/protocol/HunterProProtocol.java index ed4289d73..64dab33b1 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocol.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class HunterProProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/IdplProtocol.java b/src/main/java/org/traccar/protocol/IdplProtocol.java index aa1f4ff5b..1e44ad74c 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocol.java +++ b/src/main/java/org/traccar/protocol/IdplProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class IdplProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocol.java b/src/main/java/org/traccar/protocol/IntellitracProtocol.java index b1a91cca9..a82e6a5db 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocol.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class IntellitracProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/IotmProtocol.java b/src/main/java/org/traccar/protocol/IotmProtocol.java index 0d288f4bf..1631b67d8 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocol.java +++ b/src/main/java/org/traccar/protocol/IotmProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class IotmProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ItsProtocol.java b/src/main/java/org/traccar/protocol/ItsProtocol.java index 5148e8ab0..7d59ea60c 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocol.java +++ b/src/main/java/org/traccar/protocol/ItsProtocol.java @@ -23,7 +23,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ItsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Ivt401Protocol.java b/src/main/java/org/traccar/protocol/Ivt401Protocol.java index 763457641..5132c7467 100644 --- a/src/main/java/org/traccar/protocol/Ivt401Protocol.java +++ b/src/main/java/org/traccar/protocol/Ivt401Protocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Ivt401Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/JidoProtocol.java b/src/main/java/org/traccar/protocol/JidoProtocol.java index 78aa6c81c..b30cc586a 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocol.java +++ b/src/main/java/org/traccar/protocol/JidoProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class JidoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java index 30c8e9977..ae312ea3e 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class JpKorjarProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java index bf0b3379e..9dc62662f 100644 --- a/src/main/java/org/traccar/protocol/Jt600Protocol.java +++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Jt600Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/KenjiProtocol.java b/src/main/java/org/traccar/protocol/KenjiProtocol.java index 8d78c8c56..b4e610cbd 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocol.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocol.java @@ -24,7 +24,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class KenjiProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java index 521274de5..add13ef16 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocol.java +++ b/src/main/java/org/traccar/protocol/KhdProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class KhdProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/L100Protocol.java b/src/main/java/org/traccar/protocol/L100Protocol.java index 0edea6095..fa6d1b07e 100644 --- a/src/main/java/org/traccar/protocol/L100Protocol.java +++ b/src/main/java/org/traccar/protocol/L100Protocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class L100Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/LacakProtocol.java b/src/main/java/org/traccar/protocol/LacakProtocol.java index bbebd51ed..ddaf5078d 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocol.java +++ b/src/main/java/org/traccar/protocol/LacakProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class LacakProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java index 809fafc90..66aab3490 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java @@ -24,8 +24,8 @@ import org.traccar.Protocol; import org.traccar.helper.DateUtil; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java index 249d3bcbe..65b1a57e9 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocol.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class LaipacProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java index 7e13e23d0..9e167e7ba 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -24,7 +24,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class LeafSpyProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/M2cProtocol.java b/src/main/java/org/traccar/protocol/M2cProtocol.java index a23ea0f57..8abc30f60 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocol.java +++ b/src/main/java/org/traccar/protocol/M2cProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class M2cProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/M2mProtocol.java b/src/main/java/org/traccar/protocol/M2mProtocol.java index 6809d800c..03a069d66 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocol.java +++ b/src/main/java/org/traccar/protocol/M2mProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class M2mProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MaestroProtocol.java b/src/main/java/org/traccar/protocol/MaestroProtocol.java index 38a67f9a4..29f0b8897 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocol.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MaestroProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocol.java b/src/main/java/org/traccar/protocol/ManPowerProtocol.java index 492e86605..ba2414ca7 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ManPowerProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java index cf65a2db3..916fb7467 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java +++ b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Mavlink2Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MegastekProtocol.java b/src/main/java/org/traccar/protocol/MegastekProtocol.java index 10215eb7c..9f8937f01 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocol.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MegastekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index 492094ce3..d86a00fb3 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MeiligaoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index c6eba8fe1..4109b22c9 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MeitrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java index ccbc4db4c..08bbe0c82 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MictrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocol.java b/src/main/java/org/traccar/protocol/MilesmateProtocol.java index 59212e791..607dfc5bf 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocol.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MilesmateProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index 44599accc..1cb2a0007 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MiniFinderProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index 842194235..c12933b81 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -24,7 +24,7 @@ import org.traccar.model.Command; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Minifinder2Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index 1b06c2249..36d6b5ed2 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocol.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MobilogixProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocol.java b/src/main/java/org/traccar/protocol/MoovboxProtocol.java index 16438e122..af853fe67 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocol.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MoovboxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MotorProtocol.java b/src/main/java/org/traccar/protocol/MotorProtocol.java index 3101c9b75..f17886577 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocol.java +++ b/src/main/java/org/traccar/protocol/MotorProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MotorProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Mta6Protocol.java b/src/main/java/org/traccar/protocol/Mta6Protocol.java index 019fe4fa9..c1c6eb829 100644 --- a/src/main/java/org/traccar/protocol/Mta6Protocol.java +++ b/src/main/java/org/traccar/protocol/Mta6Protocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Mta6Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MtxProtocol.java b/src/main/java/org/traccar/protocol/MtxProtocol.java index e085b6221..12d324019 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocol.java +++ b/src/main/java/org/traccar/protocol/MtxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MtxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/MxtProtocol.java b/src/main/java/org/traccar/protocol/MxtProtocol.java index 1190bf527..2f0cc1658 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocol.java +++ b/src/main/java/org/traccar/protocol/MxtProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class MxtProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NavigilProtocol.java b/src/main/java/org/traccar/protocol/NavigilProtocol.java index 46a6c33a5..a309235c5 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocol.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NavigilProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NavisProtocol.java b/src/main/java/org/traccar/protocol/NavisProtocol.java index 640a77803..96b5b0de0 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NavisProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java index 388f141f8..6df0b0436 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NavisetProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index 50013d1a4..de5f93df1 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NavtelecomProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NdtpV6Protocol.java b/src/main/java/org/traccar/protocol/NdtpV6Protocol.java index ce0dbbef2..9493132f5 100644 --- a/src/main/java/org/traccar/protocol/NdtpV6Protocol.java +++ b/src/main/java/org/traccar/protocol/NdtpV6Protocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NdtpV6Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NeosProtocol.java b/src/main/java/org/traccar/protocol/NeosProtocol.java index 0787b6562..16a6ba5a0 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocol.java +++ b/src/main/java/org/traccar/protocol/NeosProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NeosProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NetProtocol.java b/src/main/java/org/traccar/protocol/NetProtocol.java index f27e4afb8..e011660da 100644 --- a/src/main/java/org/traccar/protocol/NetProtocol.java +++ b/src/main/java/org/traccar/protocol/NetProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NetProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NiotProtocol.java b/src/main/java/org/traccar/protocol/NiotProtocol.java index 0fbe0c689..7eacd5ff3 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocol.java +++ b/src/main/java/org/traccar/protocol/NiotProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NiotProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java index 626991029..d03e52be5 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocol.java +++ b/src/main/java/org/traccar/protocol/NoranProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NoranProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NvsProtocol.java b/src/main/java/org/traccar/protocol/NvsProtocol.java index 7ed488e38..8a4ece30d 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocol.java +++ b/src/main/java/org/traccar/protocol/NvsProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NvsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/NyitechProtocol.java b/src/main/java/org/traccar/protocol/NyitechProtocol.java index e7ef10945..225b1bd5a 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocol.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class NyitechProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java index 94f450426..9fcc35d0d 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ObdDongleProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OigoProtocol.java b/src/main/java/org/traccar/protocol/OigoProtocol.java index 0539bada6..3483f8270 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocol.java +++ b/src/main/java/org/traccar/protocol/OigoProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OigoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OkoProtocol.java b/src/main/java/org/traccar/protocol/OkoProtocol.java index 29c8bc1b9..6ca6c0e93 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocol.java +++ b/src/main/java/org/traccar/protocol/OkoProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OkoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocol.java b/src/main/java/org/traccar/protocol/OmnicommProtocol.java index dd400c779..b59b84132 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocol.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OmnicommProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java index 5443b4ffc..24d6de706 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OpenGtsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java index fb09f0abb..06b00619c 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocol.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerClient; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OrbcommProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 1164d72a1..7ed13d647 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -24,10 +24,10 @@ import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonValue; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonValue; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/OrionProtocol.java b/src/main/java/org/traccar/protocol/OrionProtocol.java index 2dec7cd06..b78af462b 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocol.java +++ b/src/main/java/org/traccar/protocol/OrionProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OrionProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocol.java b/src/main/java/org/traccar/protocol/OsmAndProtocol.java index a86bc70d7..e06580949 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocol.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OsmAndProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocol.java b/src/main/java/org/traccar/protocol/OutsafeProtocol.java index 0099be456..159534883 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocol.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OutsafeProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java index 62b873be7..f71778412 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java @@ -23,11 +23,11 @@ import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonNumber; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.json.JsonValue; +import jakarta.json.Json; +import jakarta.json.JsonNumber; +import jakarta.json.JsonObject; +import jakarta.json.JsonString; +import jakarta.json.JsonValue; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java index 9ad337f19..c509ad282 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java @@ -24,7 +24,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class OwnTracksProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java index 71ac87168..e54d07fa7 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java @@ -25,8 +25,8 @@ import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java index 709729ef1..a315d4d9f 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PacificTrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocol.java b/src/main/java/org/traccar/protocol/PathAwayProtocol.java index 1d13eea95..a65740475 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocol.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PathAwayProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocol.java b/src/main/java/org/traccar/protocol/PiligrimProtocol.java index aa45a0def..9dd1bc491 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocol.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PiligrimProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java index b2101b18d..fff1830e8 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocol.java +++ b/src/main/java/org/traccar/protocol/PluginProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PluginProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PolteProtocol.java b/src/main/java/org/traccar/protocol/PolteProtocol.java index 69666cc0e..0fbedfb09 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocol.java +++ b/src/main/java/org/traccar/protocol/PolteProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PolteProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java index 028de5424..8954db491 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java @@ -23,8 +23,8 @@ import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/PortmanProtocol.java b/src/main/java/org/traccar/protocol/PortmanProtocol.java index de78013fa..3a4b49289 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocol.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PortmanProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java index b77dd97bf..54a34fc69 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocol.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PretraceProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PricolProtocol.java b/src/main/java/org/traccar/protocol/PricolProtocol.java index f5e904541..7b0e7386c 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocol.java +++ b/src/main/java/org/traccar/protocol/PricolProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PricolProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ProgressProtocol.java b/src/main/java/org/traccar/protocol/ProgressProtocol.java index 49eb6847f..8d159ef24 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocol.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ProgressProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/PstProtocol.java b/src/main/java/org/traccar/protocol/PstProtocol.java index 73f978cbd..01a83b31f 100644 --- a/src/main/java/org/traccar/protocol/PstProtocol.java +++ b/src/main/java/org/traccar/protocol/PstProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class PstProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java index b272582a4..fd67b1241 100644 --- a/src/main/java/org/traccar/protocol/Pt215Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Pt215Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Pt3000Protocol.java b/src/main/java/org/traccar/protocol/Pt3000Protocol.java index d72774f47..5f49084ed 100644 --- a/src/main/java/org/traccar/protocol/Pt3000Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt3000Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Pt3000Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java index d5d30e8e8..0257dd60f 100644 --- a/src/main/java/org/traccar/protocol/Pt502Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Pt502Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Pt60Protocol.java b/src/main/java/org/traccar/protocol/Pt60Protocol.java index 58345f025..83e3bfbeb 100644 --- a/src/main/java/org/traccar/protocol/Pt60Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt60Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Pt60Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/R12wProtocol.java b/src/main/java/org/traccar/protocol/R12wProtocol.java index a406f6306..b5b3eff81 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocol.java +++ b/src/main/java/org/traccar/protocol/R12wProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class R12wProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java index 63ca3476c..6f7340902 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RaceDynamicsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RadarProtocol.java b/src/main/java/org/traccar/protocol/RadarProtocol.java index 9d88c6d72..8985e0e83 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocol.java +++ b/src/main/java/org/traccar/protocol/RadarProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RadarProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RaveonProtocol.java b/src/main/java/org/traccar/protocol/RaveonProtocol.java index db70396ee..aa1a79219 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocol.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RaveonProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RecodaProtocol.java b/src/main/java/org/traccar/protocol/RecodaProtocol.java index 0d50db01e..7d2fadae4 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocol.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RecodaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java index 1d4b419bb..a349a8191 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RetranslatorProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocol.java b/src/main/java/org/traccar/protocol/RfTrackProtocol.java index d3b41e93e..ac033c348 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RfTrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java index 28a3ac29c..cbb204e3b 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -29,9 +29,9 @@ import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; import org.traccar.session.DeviceSession; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/protocol/RitiProtocol.java b/src/main/java/org/traccar/protocol/RitiProtocol.java index 9b9c00cb2..9916042a8 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocol.java +++ b/src/main/java/org/traccar/protocol/RitiProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RitiProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java index ab2bc5842..229c343bb 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RoboTrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java index 109d91b16..0bb809a49 100644 --- a/src/main/java/org/traccar/protocol/RstProtocol.java +++ b/src/main/java/org/traccar/protocol/RstProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RstProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java index 99a9686f6..9f399e299 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class RuptelaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/S168Protocol.java b/src/main/java/org/traccar/protocol/S168Protocol.java index f904ed9ff..5fb0c6e72 100644 --- a/src/main/java/org/traccar/protocol/S168Protocol.java +++ b/src/main/java/org/traccar/protocol/S168Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class S168Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SabertekProtocol.java b/src/main/java/org/traccar/protocol/SabertekProtocol.java index 403243cdc..cb3f2ab32 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocol.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SabertekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SanavProtocol.java b/src/main/java/org/traccar/protocol/SanavProtocol.java index 1a0e7b0e9..ac1941725 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocol.java +++ b/src/main/java/org/traccar/protocol/SanavProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SanavProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SanulProtocol.java b/src/main/java/org/traccar/protocol/SanulProtocol.java index ea44bf868..cba162296 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocol.java +++ b/src/main/java/org/traccar/protocol/SanulProtocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SanulProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SatsolProtocol.java b/src/main/java/org/traccar/protocol/SatsolProtocol.java index d90033e38..7252f99f0 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocol.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SatsolProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocol.java b/src/main/java/org/traccar/protocol/SigfoxProtocol.java index 9a268af62..edd624727 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocol.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SigfoxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index 4ed2bb51d..1298112d1 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -32,11 +32,11 @@ import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; -import javax.json.Json; -import javax.json.JsonNumber; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.json.JsonValue; +import jakarta.json.Json; +import jakarta.json.JsonNumber; +import jakarta.json.JsonObject; +import jakarta.json.JsonString; +import jakarta.json.JsonValue; import java.io.StringReader; import java.net.SocketAddress; import java.net.URLDecoder; diff --git a/src/main/java/org/traccar/protocol/SiwiProtocol.java b/src/main/java/org/traccar/protocol/SiwiProtocol.java index f12958a50..59b96bf72 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocol.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SiwiProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java index 7ae26f634..615ef536d 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SkypatrolProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java index cb7efb7ee..e4838581a 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SmartSoleProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocol.java b/src/main/java/org/traccar/protocol/SmokeyProtocol.java index 22b343537..0aa2bcfa7 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocol.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SmokeyProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java index 0676aa629..e00f27b9b 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SolarPoweredProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SpotProtocol.java b/src/main/java/org/traccar/protocol/SpotProtocol.java index 6bd802fed..4fc57f177 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocol.java +++ b/src/main/java/org/traccar/protocol/SpotProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SpotProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocol.java b/src/main/java/org/traccar/protocol/StarLinkProtocol.java index d578fa705..6dcd40fbf 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocol.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class StarLinkProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/StarcomProtocol.java b/src/main/java/org/traccar/protocol/StarcomProtocol.java index 33c3a4776..458220e59 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocol.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class StarcomProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/StartekProtocol.java b/src/main/java/org/traccar/protocol/StartekProtocol.java index 1b1c93e33..550545345 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocol.java +++ b/src/main/java/org/traccar/protocol/StartekProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class StartekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index af4e0d2c4..0beaed39c 100644 --- a/src/main/java/org/traccar/protocol/StbProtocol.java +++ b/src/main/java/org/traccar/protocol/StbProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class StbProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index 641359bfd..c52ab485f 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -22,9 +22,9 @@ import org.traccar.Protocol; import org.traccar.model.Position; import org.traccar.session.DeviceSession; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonValue; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonValue; import java.io.StringReader; import java.net.SocketAddress; import java.util.Date; diff --git a/src/main/java/org/traccar/protocol/Stl060Protocol.java b/src/main/java/org/traccar/protocol/Stl060Protocol.java index 83b5db3bb..ac23ab3ee 100644 --- a/src/main/java/org/traccar/protocol/Stl060Protocol.java +++ b/src/main/java/org/traccar/protocol/Stl060Protocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Stl060Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java index 4253b761b..0cc5fc75c 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocol.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SuntechProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SupermateProtocol.java b/src/main/java/org/traccar/protocol/SupermateProtocol.java index 4290b7126..064f12b4b 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocol.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SupermateProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java index 7c6624f7c..a903d503c 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocol.java +++ b/src/main/java/org/traccar/protocol/SviasProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SviasProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocol.java b/src/main/java/org/traccar/protocol/SwiftechProtocol.java index 68cf40d84..d5fa5c5d3 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocol.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class SwiftechProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/T55Protocol.java b/src/main/java/org/traccar/protocol/T55Protocol.java index cedac275f..e76959fea 100644 --- a/src/main/java/org/traccar/protocol/T55Protocol.java +++ b/src/main/java/org/traccar/protocol/T55Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class T55Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/T57Protocol.java b/src/main/java/org/traccar/protocol/T57Protocol.java index 4bafe8c6d..e6ef4ccc9 100644 --- a/src/main/java/org/traccar/protocol/T57Protocol.java +++ b/src/main/java/org/traccar/protocol/T57Protocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class T57Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/T622IridiumProtocol.java b/src/main/java/org/traccar/protocol/T622IridiumProtocol.java index 1289fe8e7..22efa38a8 100644 --- a/src/main/java/org/traccar/protocol/T622IridiumProtocol.java +++ b/src/main/java/org/traccar/protocol/T622IridiumProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class T622IridiumProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index 253c3cb73..f50f22a18 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class T800xProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TaipProtocol.java b/src/main/java/org/traccar/protocol/TaipProtocol.java index 943ec98c5..71ab485ca 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocol.java +++ b/src/main/java/org/traccar/protocol/TaipProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TaipProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java index 191dd9ccc..a4a7460b0 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocol.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TechTltProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java index 265a3eb64..f0828a99e 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TechtoCruzProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TekProtocol.java b/src/main/java/org/traccar/protocol/TekProtocol.java index 54e860d79..56714041b 100644 --- a/src/main/java/org/traccar/protocol/TekProtocol.java +++ b/src/main/java/org/traccar/protocol/TekProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocol.java b/src/main/java/org/traccar/protocol/TelemaxProtocol.java index 9e9cbb50e..792a5b176 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocol.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TelemaxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TelicProtocol.java b/src/main/java/org/traccar/protocol/TelicProtocol.java index 9ef7864ca..fc5bdf0d1 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocol.java +++ b/src/main/java/org/traccar/protocol/TelicProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TelicProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java index 38283cb64..f2d610251 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TeltonikaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java index 73219cc5e..e872ddf42 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TeraTrackProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index 423ae3ffe..be4b98e4c 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -23,8 +23,8 @@ import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import javax.json.Json; -import javax.json.JsonObject; +import jakarta.json.Json; +import jakarta.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.text.DateFormat; diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java index 38bf078aa..b23dadf08 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ThinkPowerProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java index 782b0a352..34b80ba87 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ThinkRaceProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocol.java b/src/main/java/org/traccar/protocol/ThurayaProtocol.java index f709a1183..33d486f6b 100644 --- a/src/main/java/org/traccar/protocol/ThurayaProtocol.java +++ b/src/main/java/org/traccar/protocol/ThurayaProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class ThurayaProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Tk102Protocol.java b/src/main/java/org/traccar/protocol/Tk102Protocol.java index 150e83ab3..b6a82981b 100644 --- a/src/main/java/org/traccar/protocol/Tk102Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk102Protocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Tk102Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java index cf09886f5..b641ef083 100644 --- a/src/main/java/org/traccar/protocol/Tk103Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Tk103Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java index b10271f7d..6763e9b6b 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Tlt2hProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TlvProtocol.java b/src/main/java/org/traccar/protocol/TlvProtocol.java index 9d83388c9..f99676d23 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocol.java +++ b/src/main/java/org/traccar/protocol/TlvProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TlvProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TmgProtocol.java b/src/main/java/org/traccar/protocol/TmgProtocol.java index e078c425b..dbba648be 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocol.java +++ b/src/main/java/org/traccar/protocol/TmgProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TmgProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocol.java b/src/main/java/org/traccar/protocol/TopflytechProtocol.java index 339d2fc8d..a658235ab 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocol.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TopflytechProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index 37afac582..1a558f617 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocol.java +++ b/src/main/java/org/traccar/protocol/TopinProtocol.java @@ -22,7 +22,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TopinProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index 9ab36fd0b..b02d4f1fc 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -23,7 +23,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TotemProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Tr20Protocol.java b/src/main/java/org/traccar/protocol/Tr20Protocol.java index 615fdab28..3b3fc02b6 100644 --- a/src/main/java/org/traccar/protocol/Tr20Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr20Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Tr20Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Tr900Protocol.java b/src/main/java/org/traccar/protocol/Tr900Protocol.java index 162cbe651..c5f357604 100644 --- a/src/main/java/org/traccar/protocol/Tr900Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr900Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Tr900Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocol.java b/src/main/java/org/traccar/protocol/TrackboxProtocol.java index 4236144a3..eadcd07f9 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocol.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TrackboxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocol.java b/src/main/java/org/traccar/protocol/TrakMateProtocol.java index b7637e6f3..f4e7c5e60 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocol.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TrakMateProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TramigoProtocol.java b/src/main/java/org/traccar/protocol/TramigoProtocol.java index 79a59abd3..5d8baf2a9 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocol.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TramigoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocol.java b/src/main/java/org/traccar/protocol/TranSyncProtocol.java index fcc02a781..fb37a1ab4 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocol.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TranSyncProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TrvProtocol.java b/src/main/java/org/traccar/protocol/TrvProtocol.java index e67afbda2..7bdf3d2d0 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocol.java +++ b/src/main/java/org/traccar/protocol/TrvProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TrvProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Tt8850Protocol.java b/src/main/java/org/traccar/protocol/Tt8850Protocol.java index ab109e274..8e2800d90 100644 --- a/src/main/java/org/traccar/protocol/Tt8850Protocol.java +++ b/src/main/java/org/traccar/protocol/Tt8850Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Tt8850Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TytanProtocol.java b/src/main/java/org/traccar/protocol/TytanProtocol.java index cc3bc9b52..4fd3c807f 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocol.java +++ b/src/main/java/org/traccar/protocol/TytanProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TytanProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/TzoneProtocol.java b/src/main/java/org/traccar/protocol/TzoneProtocol.java index d25757b63..2df721049 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocol.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class TzoneProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocol.java b/src/main/java/org/traccar/protocol/UlbotechProtocol.java index 57fc47644..f8c4f1960 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocol.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class UlbotechProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/UproProtocol.java b/src/main/java/org/traccar/protocol/UproProtocol.java index e27088594..cbec9777d 100644 --- a/src/main/java/org/traccar/protocol/UproProtocol.java +++ b/src/main/java/org/traccar/protocol/UproProtocol.java @@ -22,7 +22,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class UproProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/UuxProtocol.java b/src/main/java/org/traccar/protocol/UuxProtocol.java index 3de4a4732..63727cb94 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocol.java +++ b/src/main/java/org/traccar/protocol/UuxProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class UuxProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/V680Protocol.java b/src/main/java/org/traccar/protocol/V680Protocol.java index 53bca849c..587a0c8f7 100644 --- a/src/main/java/org/traccar/protocol/V680Protocol.java +++ b/src/main/java/org/traccar/protocol/V680Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class V680Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocol.java b/src/main/java/org/traccar/protocol/VisiontekProtocol.java index 5296402b4..83bcd37ff 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocol.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class VisiontekProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/VltProtocol.java b/src/main/java/org/traccar/protocol/VltProtocol.java index ebced83b1..005cd8ffb 100644 --- a/src/main/java/org/traccar/protocol/VltProtocol.java +++ b/src/main/java/org/traccar/protocol/VltProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class VltProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/VnetProtocol.java b/src/main/java/org/traccar/protocol/VnetProtocol.java index dd739f0d9..6ccc54483 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocol.java +++ b/src/main/java/org/traccar/protocol/VnetProtocol.java @@ -23,7 +23,7 @@ import org.traccar.config.Config; import java.nio.ByteOrder; -import javax.inject.Inject; +import jakarta.inject.Inject; public class VnetProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Vt200Protocol.java b/src/main/java/org/traccar/protocol/Vt200Protocol.java index efb5fe2fd..97e64b74f 100644 --- a/src/main/java/org/traccar/protocol/Vt200Protocol.java +++ b/src/main/java/org/traccar/protocol/Vt200Protocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Vt200Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocol.java b/src/main/java/org/traccar/protocol/VtfmsProtocol.java index 482ab4a37..91453c413 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocol.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class VtfmsProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java index 600f81328..aee70b6ec 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocol.java +++ b/src/main/java/org/traccar/protocol/WatchProtocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class WatchProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index a744349cd..84033132d 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -27,7 +27,7 @@ import org.traccar.model.Command; import java.nio.charset.StandardCharsets; -import javax.inject.Inject; +import jakarta.inject.Inject; public class WialonProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/WliProtocol.java b/src/main/java/org/traccar/protocol/WliProtocol.java index f7084e55b..5b9ebb520 100644 --- a/src/main/java/org/traccar/protocol/WliProtocol.java +++ b/src/main/java/org/traccar/protocol/WliProtocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class WliProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java index 5a0401df4..e27b8e2bb 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocol.java +++ b/src/main/java/org/traccar/protocol/WondexProtocol.java @@ -22,7 +22,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class WondexProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/WristbandProtocol.java b/src/main/java/org/traccar/protocol/WristbandProtocol.java index c5d8d4050..117daf8cf 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocol.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocol.java @@ -21,7 +21,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class WristbandProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 52cf731f0..9dd517cfa 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -21,7 +21,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Xexun2Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java index 5c7329603..e76e47d19 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocol.java +++ b/src/main/java/org/traccar/protocol/XexunProtocol.java @@ -25,7 +25,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class XexunProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java index 0841d86d5..7e14c6842 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocol.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java @@ -24,7 +24,7 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; -import javax.inject.Inject; +import jakarta.inject.Inject; public class XirgoProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java index 65c2a1230..135fb0928 100644 --- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java +++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java @@ -26,7 +26,7 @@ import org.traccar.model.Command; import java.nio.charset.StandardCharsets; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Xrb28Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Xt013Protocol.java b/src/main/java/org/traccar/protocol/Xt013Protocol.java index 9e9087609..25809463a 100644 --- a/src/main/java/org/traccar/protocol/Xt013Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt013Protocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Xt013Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/Xt2400Protocol.java b/src/main/java/org/traccar/protocol/Xt2400Protocol.java index e200adb9f..1b7fc840b 100644 --- a/src/main/java/org/traccar/protocol/Xt2400Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt2400Protocol.java @@ -20,7 +20,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class Xt2400Protocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/protocol/YwtProtocol.java b/src/main/java/org/traccar/protocol/YwtProtocol.java index fb44e2360..27c71cfa8 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocol.java +++ b/src/main/java/org/traccar/protocol/YwtProtocol.java @@ -23,7 +23,7 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; -import javax.inject.Inject; +import jakarta.inject.Inject; public class YwtProtocol extends BaseProtocol { diff --git a/src/main/java/org/traccar/reports/CombinedReportProvider.java b/src/main/java/org/traccar/reports/CombinedReportProvider.java index 63d6a9830..bad3a61b3 100644 --- a/src/main/java/org/traccar/reports/CombinedReportProvider.java +++ b/src/main/java/org/traccar/reports/CombinedReportProvider.java @@ -28,7 +28,7 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.ArrayList; import java.util.Collection; import java.util.Date; diff --git a/src/main/java/org/traccar/reports/CsvExportProvider.java b/src/main/java/org/traccar/reports/CsvExportProvider.java index df55c470e..521dc120a 100644 --- a/src/main/java/org/traccar/reports/CsvExportProvider.java +++ b/src/main/java/org/traccar/reports/CsvExportProvider.java @@ -21,7 +21,7 @@ import org.traccar.model.Position; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Date; diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index ff7bc8e2f..f252f28cc 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -35,7 +35,7 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.File; import java.io.FileInputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/reports/GpxExportProvider.java b/src/main/java/org/traccar/reports/GpxExportProvider.java index ccbd97fc3..1c45b6416 100644 --- a/src/main/java/org/traccar/reports/GpxExportProvider.java +++ b/src/main/java/org/traccar/reports/GpxExportProvider.java @@ -24,7 +24,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Date; diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java index 24fcfb8ab..24dca018c 100644 --- a/src/main/java/org/traccar/reports/KmlExportProvider.java +++ b/src/main/java/org/traccar/reports/KmlExportProvider.java @@ -23,7 +23,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.OutputStream; import java.io.PrintWriter; import java.text.SimpleDateFormat; diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 5343652b7..d761fe1e5 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -32,7 +32,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.File; import java.io.FileInputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 57c57079d..2160fec0e 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -31,7 +31,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.File; import java.io.FileInputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 2226263fa..ffde0b067 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -35,7 +35,7 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.File; import java.io.FileInputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index e6c3e7ffd..9ff7232af 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -31,7 +31,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.File; import java.io.FileInputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/reports/common/ReportMailer.java b/src/main/java/org/traccar/reports/common/ReportMailer.java index 3ce41934f..9fb30fe9f 100644 --- a/src/main/java/org/traccar/reports/common/ReportMailer.java +++ b/src/main/java/org/traccar/reports/common/ReportMailer.java @@ -22,11 +22,11 @@ import org.traccar.mail.MailManager; import org.traccar.model.User; import org.traccar.storage.StorageException; -import javax.activation.DataHandler; -import javax.inject.Inject; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.util.ByteArrayDataSource; +import jakarta.activation.DataHandler; +import jakarta.inject.Inject; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.util.ByteArrayDataSource; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 995e92676..43db82708 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -52,8 +52,8 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.annotation.Nullable; -import javax.inject.Inject; +import jakarta.annotation.Nullable; +import jakarta.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index e1de3b3af..07cdb1fe1 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -18,8 +18,8 @@ package org.traccar.schedule; import com.google.inject.Injector; import org.traccar.LifecycleObject; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index 81567ec31..8e45568d5 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java @@ -27,7 +27,7 @@ import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; diff --git a/src/main/java/org/traccar/schedule/TaskHealthCheck.java b/src/main/java/org/traccar/schedule/TaskHealthCheck.java index a8c9873ce..abdc5af48 100644 --- a/src/main/java/org/traccar/schedule/TaskHealthCheck.java +++ b/src/main/java/org/traccar/schedule/TaskHealthCheck.java @@ -22,8 +22,8 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; -import javax.ws.rs.client.Client; +import jakarta.inject.Inject; +import jakarta.ws.rs.client.Client; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/org/traccar/schedule/TaskReports.java b/src/main/java/org/traccar/schedule/TaskReports.java index 176b6d537..30f20f437 100644 --- a/src/main/java/org/traccar/schedule/TaskReports.java +++ b/src/main/java/org/traccar/schedule/TaskReports.java @@ -39,7 +39,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.Collections; import java.util.Date; import java.util.List; diff --git a/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java b/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java index e6c2e8b6d..d9e0c6f0b 100644 --- a/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java +++ b/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java @@ -17,7 +17,7 @@ package org.traccar.schedule; import org.traccar.session.ConnectionManager; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index e6f5d00cf..28214840d 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -39,8 +39,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Arrays; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 24abd7347..58320cf29 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -40,8 +40,8 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; -import javax.inject.Inject; -import javax.inject.Singleton; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Arrays; import java.util.Collection; import java.util.Collections; diff --git a/src/main/java/org/traccar/sms/HttpSmsClient.java b/src/main/java/org/traccar/sms/HttpSmsClient.java index b4271a6f2..a2a0dd57f 100644 --- a/src/main/java/org/traccar/sms/HttpSmsClient.java +++ b/src/main/java/org/traccar/sms/HttpSmsClient.java @@ -21,11 +21,11 @@ import org.traccar.config.Keys; import org.traccar.helper.DataConverter; import org.traccar.notification.MessageException; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java b/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java index edf089f37..60ad65f9e 100644 --- a/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java +++ b/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java @@ -17,11 +17,11 @@ package org.traccar.speedlimit; import org.traccar.helper.UnitsConverter; -import javax.json.JsonArray; -import javax.json.JsonObject; -import javax.ws.rs.client.AsyncInvoker; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.InvocationCallback; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.AsyncInvoker; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.InvocationCallback; public class OverpassSpeedLimitProvider implements SpeedLimitProvider { diff --git a/src/main/java/org/traccar/storage/DatabaseModule.java b/src/main/java/org/traccar/storage/DatabaseModule.java index 3e3483818..9d9e5bd5e 100644 --- a/src/main/java/org/traccar/storage/DatabaseModule.java +++ b/src/main/java/org/traccar/storage/DatabaseModule.java @@ -29,7 +29,7 @@ import liquibase.resource.ResourceAccessor; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import javax.sql.DataSource; import java.io.File; import java.io.IOException; diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index a049a641c..d20429319 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -27,7 +27,7 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.inject.Inject; +import jakarta.inject.Inject; import javax.sql.DataSource; import java.sql.SQLException; import java.util.HashMap; diff --git a/src/main/java/org/traccar/web/ConsoleServlet.java b/src/main/java/org/traccar/web/ConsoleServlet.java index 902a4f7a9..0012ba077 100644 --- a/src/main/java/org/traccar/web/ConsoleServlet.java +++ b/src/main/java/org/traccar/web/ConsoleServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -16,7 +16,7 @@ package org.traccar.web; import org.h2.server.web.ConnectionInfo; -import org.h2.server.web.WebServlet; +import org.h2.server.web.JakartaWebServlet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; @@ -26,7 +26,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -public class ConsoleServlet extends WebServlet { +public class ConsoleServlet extends JakartaWebServlet { private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleServlet.class); @@ -41,7 +41,7 @@ public class ConsoleServlet extends WebServlet { super.init(); try { - Field field = WebServlet.class.getDeclaredField("server"); + Field field = JakartaWebServlet.class.getDeclaredField("server"); field.setAccessible(true); org.h2.server.web.WebServer server = (org.h2.server.web.WebServer) field.get(this); diff --git a/src/main/java/org/traccar/web/ModernDefaultServlet.java b/src/main/java/org/traccar/web/ModernDefaultServlet.java index 7911c0e7f..a7c8cdb29 100644 --- a/src/main/java/org/traccar/web/ModernDefaultServlet.java +++ b/src/main/java/org/traccar/web/ModernDefaultServlet.java @@ -20,7 +20,7 @@ import org.eclipse.jetty.util.resource.Resource; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.File; import java.io.IOException; diff --git a/src/main/java/org/traccar/web/OverrideFilter.java b/src/main/java/org/traccar/web/OverrideFilter.java index 6d20789f2..f870c4147 100644 --- a/src/main/java/org/traccar/web/OverrideFilter.java +++ b/src/main/java/org/traccar/web/OverrideFilter.java @@ -20,15 +20,15 @@ import org.traccar.api.security.PermissionsService; import org.traccar.model.Server; import org.traccar.storage.StorageException; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Singleton diff --git a/src/main/java/org/traccar/web/ResponseWrapper.java b/src/main/java/org/traccar/web/ResponseWrapper.java index c6179a33e..a0eaf6788 100644 --- a/src/main/java/org/traccar/web/ResponseWrapper.java +++ b/src/main/java/org/traccar/web/ResponseWrapper.java @@ -15,10 +15,10 @@ */ package org.traccar.web; -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/web/ThrottlingFilter.java b/src/main/java/org/traccar/web/ThrottlingFilter.java index 6d2328562..1bad33db6 100644 --- a/src/main/java/org/traccar/web/ThrottlingFilter.java +++ b/src/main/java/org/traccar/web/ThrottlingFilter.java @@ -19,13 +19,13 @@ import org.eclipse.jetty.servlets.DoSFilter; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; @Singleton public class ThrottlingFilter extends DoSFilter { diff --git a/src/main/java/org/traccar/web/WebInjectionManagerFactory.java b/src/main/java/org/traccar/web/WebInjectionManagerFactory.java index 14d9d3dbc..3e73c41ad 100644 --- a/src/main/java/org/traccar/web/WebInjectionManagerFactory.java +++ b/src/main/java/org/traccar/web/WebInjectionManagerFactory.java @@ -23,7 +23,7 @@ import org.jvnet.hk2.guice.bridge.api.GuiceBridge; import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.traccar.Main; -import javax.annotation.Priority; +import jakarta.annotation.Priority; @Priority(20) public class WebInjectionManagerFactory implements InjectionManagerFactory { diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 184c546d5..5f27f7662 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -52,11 +52,11 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.ObjectMapperContextResolver; -import javax.servlet.DispatcherType; -import javax.servlet.ServletException; -import javax.servlet.SessionCookieConfig; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.ServletException; +import jakarta.servlet.SessionCookieConfig; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import javax.sql.DataSource; import java.io.File; import java.io.IOException; diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 7ee0e68d0..1e1a98c1e 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -3,8 +3,8 @@ package org.traccar.geocoder; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; import java.util.Locale; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java index 3e0729dff..da5ae3340 100644 --- a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java +++ b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java @@ -6,8 +6,8 @@ import org.traccar.BaseTest; import org.traccar.model.CellTower; import org.traccar.model.Network; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; diff --git a/src/test/java/org/traccar/helper/WebHelperTest.java b/src/test/java/org/traccar/helper/WebHelperTest.java index 3a7329cb8..da18be11e 100644 --- a/src/test/java/org/traccar/helper/WebHelperTest.java +++ b/src/test/java/org/traccar/helper/WebHelperTest.java @@ -2,7 +2,7 @@ package org.traccar.helper; import org.junit.jupiter.api.Test; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; diff --git a/src/test/java/org/traccar/notification/NotificiationMailTest.java b/src/test/java/org/traccar/notification/NotificiationMailTest.java index 41124140c..ccc8cc47d 100644 --- a/src/test/java/org/traccar/notification/NotificiationMailTest.java +++ b/src/test/java/org/traccar/notification/NotificiationMailTest.java @@ -3,11 +3,11 @@ package org.traccar.notification; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; +import jakarta.mail.Message; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; import java.util.Properties; public class NotificiationMailTest { diff --git a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java index 5ea13bf9c..a59d1ce91 100644 --- a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java +++ b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java @@ -3,8 +3,8 @@ package org.traccar.speedlimit; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -- cgit v1.2.3 From cadcd2676adbc1974265acb9ec6d43fc06932824 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Aug 2023 21:09:46 -0700 Subject: Atelematics battery level --- src/main/java/org/traccar/protocol/KhdProtocolDecoder.java | 3 +++ src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java index d7c236c4f..dd2e1dbfd 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java @@ -205,6 +205,9 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { } } break; + case 0x20: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; case 0x23: Network network = new Network(); int count = buf.readUnsignedByte(); diff --git a/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java index b7e868077..7cc65002b 100644 --- a/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class KhdProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,10 @@ public class KhdProtocolDecoderTest extends ProtocolTest { var decoder = inject(new KhdProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "2929a3003e1680ba0a2304180759500000000000000000000000007b00000080001914000000000000000000162001641b0b0000249002bc58030001cc46020000e70d"), + Position.KEY_BATTERY_LEVEL, 100); + verifyPosition(decoder, binary( "2929800028258b8c10210731035840031534240542120200000337fb000000ffff5a00000a0000000005005d0d")); -- cgit v1.2.3 From ee6b094d26ef8015299cd4a239a415be0cab57f0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 22 Aug 2023 06:47:29 -0700 Subject: Configurable TAIP speed unit --- src/main/java/org/traccar/protocol/TaipProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java index e5e84b7c4..cf72eef42 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java @@ -192,7 +192,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); } - position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble(0))); + position.setSpeed(convertSpeed(parser.nextDouble(0), "mph")); position.setCourse(parser.nextDouble(0)); if (parser.hasNext(2)) { -- cgit v1.2.3 From 50e730c0cbbe253b68a2db0e57920ddc3a1b3814 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 22 Aug 2023 06:50:52 -0700 Subject: Remove unused import --- src/main/java/org/traccar/protocol/TaipProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java index cf72eef42..787ed1599 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java @@ -26,7 +26,6 @@ import org.traccar.helper.DateBuilder; import org.traccar.helper.DateUtil; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -- cgit v1.2.3 From 9aeedc90da24848ff97227d6f281eb4d1e1506ef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 23 Aug 2023 21:01:38 -0700 Subject: Add speed limit multiplier (fix #5161) --- src/main/java/org/traccar/config/Keys.java | 9 +++++++++ .../java/org/traccar/handler/events/OverspeedEventHandler.java | 6 ++++-- .../java/org/traccar/session/state/OverspeedProcessor.java | 7 ++++--- .../org/traccar/handler/events/OverspeedEventHandlerTest.java | 10 +++++----- 4 files changed, 22 insertions(+), 10 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index f95794e03..27f5f0921 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -340,6 +340,15 @@ public final class Keys { List.of(KeyType.SERVER, KeyType.DEVICE), 0.0); + /** + * Speed limit threshold multiplier. For example, if the speed limit is 100, but we only want to generate an event + * if the speed is higher than 105, this parameter can be set to 1.05. Default multiplier is 1.0. + */ + public static final ConfigKey EVENT_OVERSPEED_THRESHOLD_MULTIPLIER = new DoubleConfigKey( + "event.overspeed.thresholdMultiplier", + List.of(KeyType.CONFIG), + 1.0); + /** * Minimal over speed duration to trigger the event. Value in seconds. */ diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 94fdc4699..3bb5f713c 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 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2023 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -52,6 +52,7 @@ public class OverspeedEventHandler extends BaseEventHandler { private final long minimalDuration; private final boolean preferLowest; + private final double multiplier; @Inject public OverspeedEventHandler( @@ -60,6 +61,7 @@ public class OverspeedEventHandler extends BaseEventHandler { this.storage = storage; minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); + multiplier = config.getDouble(Keys.EVENT_OVERSPEED_THRESHOLD_MULTIPLIER); } @Override @@ -107,7 +109,7 @@ public class OverspeedEventHandler extends BaseEventHandler { } OverspeedState state = OverspeedState.fromDevice(device); - OverspeedProcessor.updateState(state, position, speedLimit, minimalDuration, overspeedGeofenceId); + OverspeedProcessor.updateState(state, position, speedLimit, multiplier, minimalDuration, overspeedGeofenceId); if (state.isChanged()) { state.toDevice(device); try { diff --git a/src/main/java/org/traccar/session/state/OverspeedProcessor.java b/src/main/java/org/traccar/session/state/OverspeedProcessor.java index b23649570..221b51ff5 100644 --- a/src/main/java/org/traccar/session/state/OverspeedProcessor.java +++ b/src/main/java/org/traccar/session/state/OverspeedProcessor.java @@ -26,13 +26,14 @@ public final class OverspeedProcessor { } public static void updateState( - OverspeedState state, Position position, double speedLimit, long minimalDuration, long geofenceId) { + OverspeedState state, Position position, + double speedLimit, double multiplier, long minimalDuration, long geofenceId) { state.setEvent(null); boolean oldState = state.getOverspeedState(); if (oldState) { - boolean newState = position.getSpeed() > speedLimit; + boolean newState = position.getSpeed() > speedLimit * multiplier; if (newState) { checkEvent(state, position, speedLimit, minimalDuration); } else { @@ -40,7 +41,7 @@ public final class OverspeedProcessor { state.setOverspeedTime(null); state.setOverspeedGeofenceId(0); } - } else if (position != null && position.getSpeed() > speedLimit) { + } else if (position != null && position.getSpeed() > speedLimit * multiplier) { state.setOverspeedState(true); state.setOverspeedTime(position.getFixTime()); state.setOverspeedGeofenceId(geofenceId); diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 25e9bd265..97d929551 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -35,14 +35,14 @@ public class OverspeedEventHandlerTest extends BaseTest { private void testOverspeedWithPosition(long geofenceId) throws ParseException { OverspeedState state = new OverspeedState(); - OverspeedProcessor.updateState(state, position("2017-01-01 00:00:00", 50), 40, 15000, geofenceId); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:00", 50), 40, 1, 15000, geofenceId); assertNull(state.getEvent()); verifyState(state, true, geofenceId); - OverspeedProcessor.updateState(state, position("2017-01-01 00:00:10", 55), 40, 15000, geofenceId); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:10", 55), 40, 1, 15000, geofenceId); assertNull(state.getEvent()); - OverspeedProcessor.updateState(state, position("2017-01-01 00:00:20", 55), 40, 15000, geofenceId); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:20", 55), 40, 1, 15000, geofenceId); assertNotNull(state.getEvent()); assertEquals(Event.TYPE_DEVICE_OVERSPEED, state.getEvent().getType()); assertEquals(55, state.getEvent().getDouble("speed"), 0.1); @@ -50,11 +50,11 @@ public class OverspeedEventHandlerTest extends BaseTest { assertEquals(geofenceId, state.getEvent().getGeofenceId()); verifyState(state, true, 0); - OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 55), 40, 15000, geofenceId); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 55), 40, 1, 15000, geofenceId); assertNull(state.getEvent()); verifyState(state, true, 0); - OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 30), 40, 15000, geofenceId); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 30), 40, 1, 15000, geofenceId); assertNull(state.getEvent()); verifyState(state, false, 0); } -- cgit v1.2.3