diff options
Diffstat (limited to 'src/main/java')
88 files changed, 405 insertions, 3014 deletions
diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index aeba9c4c9..fe494dabf 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 - 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. @@ -38,7 +38,6 @@ 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; import org.traccar.database.UsersManager; import org.traccar.geocoder.Geocoder; @@ -54,7 +53,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; @@ -237,12 +235,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() { @@ -345,8 +337,6 @@ public final class Context { commandsManager = new CommandsManager(dataManager, config.getBoolean(Keys.COMMANDS_QUEUEING)); - orderManager = new OrderManager(dataManager); - } private static void initEventsModule() { @@ -407,8 +397,6 @@ public final class Context { return (BaseObjectManager<T>) maintenancesManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager<T>) notificationManager; - } else if (clazz.equals(Order.class)) { - return (BaseObjectManager<T>) orderManager; } return null; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 11100f66e..e1a4d6b1c 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@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.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.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; @@ -41,7 +40,6 @@ 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.MapmyIndiaGeocoder; import org.traccar.geocoder.NominatimGeocoder; import org.traccar.geocoder.OpenCageGeocoder; @@ -107,11 +105,6 @@ public class MainModule extends AbstractModule { } @Provides - public static ConnectionManager provideConnectionManager() { - return Context.getConnectionManager(); - } - - @Provides public static Client provideClient() { return Context.getClient(); } @@ -195,8 +188,6 @@ public class MainModule extends AbstractModule { return new PositionStackGeocoder(key, cacheSize, addressFormat); case "mapbox": return new MapboxGeocoder(key, cacheSize, addressFormat); - case "maptiler": - return new MapTilerGeocoder(key, cacheSize, addressFormat); default: return new GoogleGeocoder(key, language, cacheSize, addressFormat); } @@ -399,9 +390,8 @@ public class MainModule extends AbstractModule { @Singleton @Provides public static GeofenceEventHandler provideGeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, - ConnectionManager connectionManager) { - return new GeofenceEventHandler(identityManager, geofenceManager, calendarManager, connectionManager); + IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager) { + return new GeofenceEventHandler(identityManager, geofenceManager, calendarManager); } @Singleton diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 34e4a94ce..e0ccf7020 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -1,18 +1,3 @@ -/* - * 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. - * 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 java.sql.SQLException; @@ -22,9 +7,7 @@ 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 org.traccar.Context; import org.traccar.api.BaseResource; @@ -42,9 +25,6 @@ public class EventResource extends BaseResource { @GET public Event get(@PathParam("id") long id) throws SQLException { Event event = Context.getDataManager().getObject(Event.class, id); - if (event == null) { - 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()); diff --git a/src/main/java/org/traccar/api/resource/OrderResource.java b/src/main/java/org/traccar/api/resource/OrderResource.java deleted file mode 100644 index 77608a508..000000000 --- a/src/main/java/org/traccar/api/resource/OrderResource.java +++ /dev/null @@ -1,35 +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.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; - -@Path("orders") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class OrderResource extends SimpleObjectResource<Order> { - - public OrderResource() { - super(Order.class); - } - -} diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 1868a6191..20e8d768d 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -19,7 +19,7 @@ import org.apache.velocity.VelocityContext; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.User; -import org.traccar.notification.NotificationMessage; +import org.traccar.notification.FullMessage; import org.traccar.notification.TextTemplateFormatter; import javax.annotation.security.PermitAll; @@ -53,9 +53,8 @@ public class PasswordResource extends BaseResource { Context.getUsersManager().updateItem(user); VelocityContext velocityContext = TextTemplateFormatter.prepareContext(null); velocityContext.put("token", token); - NotificationMessage fullMessage = - TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); + FullMessage message = TextTemplateFormatter.formatFullMessage(velocityContext, "passwordReset"); + Context.getMailManager().sendMessage(userId, message.getSubject(), message.getBody()); break; } } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 60ce5490a..e3c5d457f 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 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,19 +57,8 @@ public class SessionResource extends BaseResource { @PermitAll @GET public User get(@QueryParam("token") String token) throws SQLException, UnsupportedEncodingException { - - if (token != null) { - User user = Context.getUsersManager().getUserByToken(token); - if (user != null) { - Context.getPermissionsManager().checkUserEnabled(user.getId()); - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - 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) { @@ -88,20 +77,24 @@ public class SessionResource extends BaseResource { if (email != null && password != null) { User user = Context.getPermissionsManager().login(email, password); if (user != null) { - Context.getPermissionsManager().checkUserEnabled(user.getId()); - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - return user; + userId = user.getId(); + request.getSession().setAttribute(USER_ID_KEY, userId); + } + } else if (token != null) { + User user = Context.getUsersManager().getUserByToken(token); + if (user != null) { + userId = user.getId(); + request.getSession().setAttribute(USER_ID_KEY, userId); } } + } - } else { - + if (userId != null) { Context.getPermissionsManager().checkUserEnabled(userId); return Context.getPermissionsManager().getUser(userId); - + } else { + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } - - throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } @PermitAll diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e8e0ff207..1411e8a13 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -893,11 +893,8 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * 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. + * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if they're + * marked as valid. Shouldn't be too low. Start testing with values at about 25000. */ public static final ConfigKey<Integer> FILTER_MAX_SPEED = new ConfigKey<>( "filter.maxSpeed", @@ -911,20 +908,8 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * 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. - */ - public static final ConfigKey<Boolean> FILTER_RELATIVE = new ConfigKey<>( - "filter.relative", - Collections.singletonList(KeyType.GLOBAL)); - - /** - * 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. + * Time limit for the filtering in seconds. If the time difference between last position and a new one is more than + * this limit, the new position will not be filtered out. */ public static final ConfigKey<Long> FILTER_SKIP_LIMIT = new ConfigKey<>( "filter.skipLimit", @@ -932,7 +917,6 @@ public final class Keys { /** * 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<Boolean> FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey<>( "filter.skipAttributes.enable", diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index ebd0dcade..de6da8f23 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -41,7 +41,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.Position; import org.traccar.model.Server; @@ -333,13 +332,6 @@ public class DataManager { .executeQuery(Position.class); } - public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) - .setLong("deviceId", deviceId) - .setDate("time", date) - .executeQuerySingle(Position.class); - } - public void updateLatestPosition(Position position) throws SQLException { QueryBuilder.create(dataSource, getQuery("database.updateLatestPosition")) .setDate("now", new Date()) @@ -396,8 +388,6 @@ public class DataManager { return Maintenance.class; case "notification": return Notification.class; - case "order": - return Order.class; default: throw new ClassNotFoundException(); } 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<Order> { - - 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 32464cf90..a27eac069 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -29,7 +29,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; @@ -396,8 +395,6 @@ public class PermissionsManager { 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"); } @@ -457,8 +454,6 @@ public class PermissionsManager { Context.getCommandsManager().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(); @@ -474,8 +469,6 @@ public class PermissionsManager { Context.getCommandsManager().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/geocoder/HereGeocoder.java b/src/main/java/org/traccar/geocoder/HereGeocoder.java index 40390e65b..aaf11d74d 100644 --- a/src/main/java/org/traccar/geocoder/HereGeocoder.java +++ b/src/main/java/org/traccar/geocoder/HereGeocoder.java @@ -53,8 +53,8 @@ public class HereGeocoder extends JsonGeocoder { if (result != null) { Address address = new Address(); - if (result.containsKey("Label")) { - address.setFormattedAddress(result.getString("Label")); + if (json.containsKey("Label")) { + address.setFormattedAddress(json.getString("Label")); } if (result.containsKey("HouseNumber")) { diff --git a/src/main/java/org/traccar/geocoder/JsonGeocoder.java b/src/main/java/org/traccar/geocoder/JsonGeocoder.java index f20aa79d6..3cd5b596e 100644 --- a/src/main/java/org/traccar/geocoder/JsonGeocoder.java +++ b/src/main/java/org/traccar/geocoder/JsonGeocoder.java @@ -97,9 +97,7 @@ public abstract class JsonGeocoder implements Geocoder { } } - if (Main.getInjector() != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); - } + Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); Invocation.Builder request = Context.getClient().target(String.format(url, latitude, longitude)).request(); diff --git a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java deleted file mode 100644 index 6b688a6e8..000000000 --- a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java +++ /dev/null @@ -1,73 +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.geocoder; - -import javax.json.JsonArray; -import javax.json.JsonObject; - -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); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray features = json.getJsonArray("features"); - - if (!features.isEmpty()) { - Address address = new Address(); - - for (int i = 0; i < features.size(); i++) { - JsonObject feature = features.getJsonObject(i); - String type = feature.getJsonArray("place_type").getString(0); - String value = feature.getString("text"); - switch (type) { - case "street": - address.setStreet(value); - break; - case "city": - address.setSettlement(value); - break; - case "county": - address.setDistrict(value); - break; - case "state": - address.setState(value); - break; - case "country": - address.setCountry(value); - break; - default: - break; - } - if (address.getFormattedAddress() == null) { - address.setFormattedAddress(feature.getString("place_name")); - } - } - - return address; - } - - return null; - } - - @Override - protected String parseError(JsonObject json) { - return null; - } - -} diff --git a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index 2535970d3..cb3094e16 100644 --- a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java @@ -49,15 +49,7 @@ public class OpenCellIdGeolocationProvider implements GeolocationProvider { json.getJsonNumber("lat").doubleValue(), json.getJsonNumber("lon").doubleValue(), 0); } else { - if (json.containsKey("error")) { - String errorMessage = json.getString("error"); - if (json.containsKey("code")) { - errorMessage += " (" + json.getInt("code") + ")"; - } - callback.onFailure(new GeolocationException(errorMessage)); - } else { - callback.onFailure(new GeolocationException("Coordinates are missing")); - } + callback.onFailure(new GeolocationException("Coordinates are missing")); } } diff --git a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java index 33cd84a47..f71620d8a 100644 --- a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java @@ -25,7 +25,7 @@ import javax.ws.rs.client.InvocationCallback; public class UniversalGeolocationProvider implements GeolocationProvider { - private final String url; + private String url; public UniversalGeolocationProvider(String url, String key) { this.url = url + "?key=" + key; diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 049512765..7cd9153c1 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -25,9 +25,6 @@ import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import java.sql.SQLException; -import java.util.Date; - @ChannelHandler.Sharable public class FilterHandler extends BaseDataHandler { @@ -43,7 +40,6 @@ public class FilterHandler extends BaseDataHandler { private int filterDistance; private int filterMaxSpeed; private long filterMinPeriod; - private boolean filterRelative; private long skipLimit; private boolean skipAttributes; @@ -58,15 +54,14 @@ public class FilterHandler extends BaseDataHandler { filterDistance = config.getInteger(Keys.FILTER_DISTANCE); filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED); filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000; - filterRelative = config.getBoolean(Keys.FILTER_RELATIVE); skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000; skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE); } private boolean filterInvalid(Position position) { return filterInvalid && (!position.getValid() - || position.getLatitude() > 90 || position.getLongitude() > 180 - || position.getLatitude() < -90 || position.getLongitude() < -180); + || position.getLatitude() > 90 || position.getLongitude() > 180 + || position.getLatitude() < -90 || position.getLongitude() < -180); } private boolean filterZero(Position position) { @@ -149,13 +144,20 @@ public class FilterHandler extends BaseDataHandler { StringBuilder filterType = new StringBuilder(); - // filter out invalid data + Position last = null; + if (Context.getIdentityManager() != null) { + last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + } + if (filterInvalid(position)) { filterType.append("Invalid "); } if (filterZero(position)) { filterType.append("Zero "); } + if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + filterType.append("Duplicate "); + } if (filterFuture(position)) { filterType.append("Future "); } @@ -165,37 +167,17 @@ public class FilterHandler extends BaseDataHandler { if (filterApproximate(position)) { filterType.append("Approximate "); } - - // filter out excessive data - long deviceId = position.getDeviceId(); - if (filterDuplicate || filterStatic || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { - Position preceding = null; - if (filterRelative) { - try { - Date newFixTime = position.getFixTime(); - preceding = Context.getDataManager().getPrecedingPosition(deviceId, newFixTime); - } catch (SQLException e) { - LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); - preceding = getLastReceivedPosition(deviceId); - } - } else { - preceding = getLastReceivedPosition(deviceId); - } - if (filterDuplicate(position, preceding)) { - filterType.append("Duplicate "); - } - if (filterStatic(position) && !skipLimit(position, preceding) && !skipAttributes(position)) { - filterType.append("Static "); - } - if (filterDistance(position, preceding) && !skipLimit(position, preceding) && !skipAttributes(position)) { - filterType.append("Distance "); - } - if (filterMaxSpeed(position, preceding)) { - filterType.append("MaxSpeed "); - } - if (filterMinPeriod(position, preceding)) { - filterType.append("MinPeriod "); - } + if (filterStatic(position) && !skipLimit(position, last) && !skipAttributes(position)) { + filterType.append("Static "); + } + if (filterDistance(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + filterType.append("Distance "); + } + if (filterMaxSpeed(position, last)) { + filterType.append("MaxSpeed "); + } + if (filterMinPeriod(position, last)) { + filterType.append("MinPeriod "); } if (filterType.length() > 0) { @@ -204,7 +186,7 @@ public class FilterHandler extends BaseDataHandler { message.append("Position filtered by "); message.append(filterType.toString()); message.append("filters from device: "); - message.append(Context.getIdentityManager().getById(deviceId).getUniqueId()); + message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); LOGGER.info(message.toString()); return true; @@ -213,13 +195,6 @@ public class FilterHandler extends BaseDataHandler { return false; } - private Position getLastReceivedPosition(long deviceId) { - if (Context.getIdentityManager() != null) { - return Context.getIdentityManager().getLastPosition(deviceId); - } - return null; - } - @Override protected Position handlePosition(Position position) { if (filter(position)) { diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index dae0c891f..f4807e56b 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 - 2019 Anton Tananaev (anton@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,6 @@ import java.util.Map; import io.netty.channel.ChannelHandler; import org.traccar.database.CalendarManager; -import org.traccar.database.ConnectionManager; import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Calendar; @@ -36,15 +35,12 @@ public class GeofenceEventHandler extends BaseEventHandler { private final IdentityManager identityManager; private final GeofenceManager geofenceManager; private final CalendarManager calendarManager; - private final ConnectionManager connectionManager; public GeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, - ConnectionManager connectionManager) { + IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager) { this.identityManager = identityManager; this.geofenceManager = geofenceManager; this.calendarManager = calendarManager; - this.connectionManager = connectionManager; } @Override @@ -67,9 +63,6 @@ public class GeofenceEventHandler extends BaseEventHandler { oldGeofences.removeAll(currentGeofences); device.setGeofenceIds(currentGeofences); - if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) { - connectionManager.updateDevice(device); - } Map<Event, Position> events = new HashMap<>(); for (long geofenceId : oldGeofences) { diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index bbf12d738..b086f0f9e 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,28 +28,19 @@ public final class BufferUtil { } public static int indexOf(String needle, ByteBuf haystack) { - return indexOf(needle, haystack, haystack.readerIndex(), haystack.writerIndex()); - } - - public static int indexOf(String needle, ByteBuf haystack, int startIndex, int endIndex) { - ByteBuf wrappedNeedle = Unpooled.wrappedBuffer(needle.getBytes(StandardCharsets.US_ASCII)); + ByteBuf needleBuffer = Unpooled.wrappedBuffer(needle.getBytes(StandardCharsets.US_ASCII)); try { - return indexOf(wrappedNeedle, haystack, startIndex, endIndex); + return ByteBufUtil.indexOf(needleBuffer, haystack); } finally { - wrappedNeedle.release(); + needleBuffer.release(); } } - 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 result = ByteBufUtil.indexOf(needle, wrappedHaystack); + public static int indexOf(String needle, ByteBuf haystack, int startIndex, int endIndex) { + ByteBuf wrappedHaystack = Unpooled.wrappedBuffer(haystack); + wrappedHaystack.readerIndex(startIndex - haystack.readerIndex()); + wrappedHaystack.writerIndex(endIndex - haystack.readerIndex()); + int result = indexOf(needle, wrappedHaystack); return result < 0 ? result : haystack.readerIndex() + startIndex + result; } diff --git a/src/main/java/org/traccar/model/Order.java b/src/main/java/org/traccar/model/Order.java deleted file mode 100644 index fe6d926b8..000000000 --- a/src/main/java/org/traccar/model/Order.java +++ /dev/null @@ -1,60 +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.model; - -public class Order extends ExtendedModel { - - private String uniqueId; - - public String getUniqueId() { - return uniqueId; - } - - public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId; - } - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - private String fromAddress; - - public String getFromAddress() { - return fromAddress; - } - - public void setFromAddress(String fromAddress) { - this.fromAddress = fromAddress; - } - - private String toAddress; - - public String getToAddress() { - return toAddress; - } - - public void setToAddress(String toAddress) { - this.toAddress = toAddress; - } - -} diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 09d25e832..6f70c8e21 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -136,6 +136,7 @@ public class Position extends Message { public static final String ALARM_JAMMING = "jamming"; public static final String ALARM_TEMPERATURE = "temperature"; public static final String ALARM_PARKING = "parking"; + public static final String ALARM_SHOCK = "shock"; public static final String ALARM_BONNET = "bonnet"; public static final String ALARM_FOOT_BRAKE = "footBrake"; public static final String ALARM_FUEL_LEAK = "fuelLeak"; diff --git a/src/main/java/org/traccar/notification/NotificationMessage.java b/src/main/java/org/traccar/notification/FullMessage.java index 0fb8d7654..f66537c6e 100644 --- a/src/main/java/org/traccar/notification/NotificationMessage.java +++ b/src/main/java/org/traccar/notification/FullMessage.java @@ -16,12 +16,12 @@ */ package org.traccar.notification; -public class NotificationMessage { +public class FullMessage { private String subject; private String body; - public NotificationMessage(String subject, String body) { + public FullMessage(String subject, String body) { this.subject = subject; this.body = body; } diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 9a6723a71..dabc75b8b 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -58,9 +58,14 @@ public final class NotificationFormatter { return velocityContext; } - public static NotificationMessage formatMessage(long userId, Event event, Position position, String templatePath) { + public static FullMessage formatFullMessage(long userId, Event event, Position position) { VelocityContext velocityContext = prepareContext(userId, event, position); - return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); + return TextTemplateFormatter.formatFullMessage(velocityContext, event.getType()); + } + + public static String formatShortMessage(long userId, Event event, Position position) { + VelocityContext velocityContext = prepareContext(userId, event, position); + return TextTemplateFormatter.formatShortMessage(velocityContext, event.getType()); } } diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index b7058c824..c7cac2d4d 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -71,10 +71,21 @@ public final class TextTemplateFormatter { return template; } - public static NotificationMessage formatMessage(VelocityContext velocityContext, String name, String templatePath) { + public static FullMessage formatFullMessage(VelocityContext velocityContext, String name) { + String formattedMessage = formatMessage(velocityContext, name, "full"); + return new FullMessage((String) velocityContext.get("subject"), formattedMessage); + } + + public static String formatShortMessage(VelocityContext velocityContext, String name) { + return formatMessage(velocityContext, name, "short"); + } + + private static String 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()); + return writer.toString(); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index f91ec25a0..78d5da1e2 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -24,7 +24,6 @@ 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 javax.ws.rs.client.Entity; @@ -38,8 +37,6 @@ public class NotificatorFirebase extends Notificator { private final String key; public static class Notification { - @JsonProperty("title") - private String title; @JsonProperty("body") private String body; @JsonProperty("sound") @@ -69,11 +66,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"); - Notification notification = new Notification(); - notification.title = shortMessage.getSubject(); - notification.body = shortMessage.getBody(); + notification.body = NotificationFormatter.formatShortMessage(userId, event, position).trim(); notification.sound = "default"; Message message = new Message(); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 9b5637ed8..6b9774c58 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -19,7 +19,7 @@ package org.traccar.notificators; import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.notification.NotificationMessage; +import org.traccar.notification.FullMessage; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; @@ -30,8 +30,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"); - Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); + FullMessage message = NotificationFormatter.formatFullMessage(userId, event, position); + Context.getMailManager().sendMessage(userId, message.getSubject(), message.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..189af7834 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -24,7 +24,6 @@ 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 javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -44,8 +43,6 @@ public class NotificatorPushover extends Notificator { private String user; @JsonProperty("device") private String device; - @JsonProperty("title") - private String title; @JsonProperty("message") private String message; } @@ -77,14 +74,11 @@ public class NotificatorPushover extends Notificator { return; } - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); - Message message = new Message(); message.token = token; message.user = this.user; message.device = device; - message.title = shortMessage.getSubject(); - message.message = shortMessage.getBody(); + message.message = NotificationFormatter.formatShortMessage(userId, event, position); Context.getClient().target(url).request() .async().post(Entity.json(message), new InvocationCallback<Object>() { diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index fb817b112..8124e40b1 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -24,7 +24,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; public final class NotificatorSms extends Notificator { @@ -32,10 +31,9 @@ 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"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), - shortMessage.getBody(), false); + NotificationFormatter.formatShortMessage(userId, event, position), false); } } @@ -43,10 +41,9 @@ 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"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), - shortMessage.getBody(), false); + NotificationFormatter.formatShortMessage(userId, event, position), false); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 70148110c..dbba0d31d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -25,7 +25,6 @@ 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 javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -99,14 +98,12 @@ 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"); - TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); if (message.chatId == null) { message.chatId = chatId; } - message.text = shortMessage.getBody(); + message.text = NotificationFormatter.formatShortMessage(userId, event, position); executeRequest(urlSendText, message); if (sendLocation && position != null) { executeRequest(urlSendLocation, createLocationMessage(message.chatId, position)); diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java deleted file mode 100644 index 7f08870ce..000000000 --- a/src/main/java/org/traccar/protocol/B2316Protocol.java +++ /dev/null @@ -1,37 +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.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; - -public class B2316Protocol extends BaseProtocol { - - public B2316Protocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new B2316ProtocolDecoder(B2316Protocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java deleted file mode 100644 index 854107a20..000000000 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ /dev/null @@ -1,162 +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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.model.CellTower; -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 java.io.StringReader; -import java.net.SocketAddress; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class B2316ProtocolDecoder extends BaseProtocolDecoder { - - public B2316ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_LOW_BATTERY; - case 2: - return Position.ALARM_SOS; - case 3: - return Position.ALARM_POWER_OFF; - case 4: - return Position.ALARM_REMOVING; - default: - return null; - } - } - - private Integer decodeBattery(int value) { - switch (value) { - case 0: - return 10; - case 1: - return 30; - case 2: - return 60; - case 3: - return 80; - case 4: - return 100; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - JsonObject root = Json.createReader(new StringReader((String) msg)).readObject(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, root.getString("imei")); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - JsonArray data = root.getJsonArray("data"); - for (int i = 0; i < data.size(); i++) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - Network network = new Network(); - - JsonObject item = data.getJsonObject(i); - Date time = new Date(item.getJsonNumber("tm").longValue() * 1000); - - if (item.containsKey("gp")) { - String[] coordinates = item.getString("gp").split(","); - position.setLongitude(Double.parseDouble(coordinates[0])); - position.setLatitude(Double.parseDouble(coordinates[1])); - position.setValid(true); - position.setTime(time); - } else { - getLastLocation(position, time); - } - - if (item.containsKey("ci")) { - String[] cell = item.getString("ci").split(","); - network.addCellTower(CellTower.from( - Integer.parseInt(cell[0]), Integer.parseInt(cell[1]), - Integer.parseInt(cell[2]), Integer.parseInt(cell[3]), - Integer.parseInt(cell[4]))); - } - - if (item.containsKey("wi")) { - String[] points = item.getString("wi").split(";"); - for (String point : points) { - String[] values = point.split(","); - network.addWifiAccessPoint(WifiAccessPoint.from( - values[0].replaceAll("(..)", "$1:"), Integer.parseInt(values[1]))); - } - } - - if (item.containsKey("wn")) { - position.set(Position.KEY_ALARM, decodeAlarm(item.getInt("wn"))); - } - if (item.containsKey("ic")) { - position.set(Position.KEY_ICCID, item.getString("ic")); - } - if (item.containsKey("ve")) { - position.set(Position.KEY_VERSION_FW, item.getString("ve")); - } - if (item.containsKey("te")) { - String[] temperatures = item.getString("te").split(","); - for (int j = 0; j < temperatures.length; j++) { - position.set(Position.PREFIX_TEMP + (j + 1), Integer.parseInt(temperatures[j]) * 0.1); - } - } - if (item.containsKey("st")) { - position.set(Position.KEY_STEPS, item.getInt("st")); - } - if (item.containsKey("ba")) { - position.set(Position.KEY_BATTERY_LEVEL, decodeBattery(item.getInt("ba"))); - } - if (item.containsKey("sn")) { - position.set(Position.KEY_RSSI, item.getInt("sn")); - } - if (item.containsKey("hr")) { - position.set(Position.KEY_HEART_RATE, item.getInt("hr")); - } - - if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { - position.setNetwork(network); - } - - positions.add(position); - } - - return positions.isEmpty() ? null : positions; - } - -} diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index 535827f3c..a26b8e8e6 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * 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. @@ -90,13 +90,11 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 14)) { - int mcc = buf.readUnsignedShortLE(); - int mnc = buf.readUnsignedByte(); - int lac = buf.readUnsignedShortLE(); - int cid = buf.readUnsignedShortLE(); - buf.readUnsignedByte(); // time advance - int rssi = -buf.readUnsignedByte(); - position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid, rssi))); + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShortLE(), buf.readUnsignedByte(), + buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), + buf.readUnsignedByte()))); + buf.readUnsignedByte(); } } @@ -179,16 +177,10 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShortLE(); // dallas humidity } if (BitUtil.check(mask, 9)) { - position.set("fuel1", buf.readUnsignedShortLE()); - position.set("fuelTemp1", (int) buf.readByte()); - position.set("fuel2", buf.readUnsignedShortLE()); - position.set("fuelTemp2", (int) buf.readByte()); + buf.skipBytes(6); // lls group 1 } if (BitUtil.check(mask, 10)) { - position.set("fuel3", buf.readUnsignedShortLE()); - position.set("fuelTemp3", (int) buf.readByte()); - position.set("fuel4", buf.readUnsignedShortLE()); - position.set("fuelTemp4", (int) buf.readByte()); + buf.skipBytes(6); // lls group 2 } if (BitUtil.check(mask, 11)) { buf.skipBytes(21); // j1979 group 1 diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index 83e62ff86..6a31cb2f4 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -60,7 +60,7 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { private String decodeAlarm(int alarm) { switch (alarm) { case 0x2: - return Position.ALARM_VIBRATION; + return Position.ALARM_SHOCK; case 0x3: return Position.ALARM_POWER_CUT; case 0x4: diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 815cce987..987361baf 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 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. @@ -32,11 +32,7 @@ import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.text.DateFormat; -import java.text.ParseException; import java.text.SimpleDateFormat; -import java.time.OffsetDateTime; -import java.util.Collection; -import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; @@ -55,25 +51,12 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { JsonObject root = Json.createReader( new StringReader(request.content().toString(StandardCharsets.US_ASCII))).readObject(); - Object result; - if (root.containsKey("device")) { - result = decodeEdge(channel, remoteAddress, root); - } else { - result = decodeTraditional(channel, remoteAddress, root); - } - - sendResponse(channel, result != null ? HttpResponseStatus.OK : HttpResponseStatus.BAD_REQUEST); - return result; - } - - private Collection<Position> decodeTraditional( - Channel channel, SocketAddress remoteAddress, JsonObject root) throws ParseException { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, root.getString("IMEI")); if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); return null; } @@ -143,77 +126,8 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { positions.add(position); } + sendResponse(channel, HttpResponseStatus.OK); return positions; } - private Position decodeEdge( - Channel channel, SocketAddress remoteAddress, JsonObject root) { - - JsonObject device = root.getJsonObject("device"); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, device.getString("imei")); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - Date time = new Date(OffsetDateTime.parse(root.getString("date")).toInstant().toEpochMilli()); - - if (root.containsKey("lat") && root.containsKey("lng")) { - position.setValid(true); - position.setTime(time); - position.setLatitude(root.getJsonNumber("lat").doubleValue()); - position.setLongitude(root.getJsonNumber("lng").doubleValue()); - position.setAccuracy(root.getJsonNumber("posAcc").doubleValue()); - } else { - getLastLocation(position, time); - } - - position.set(Position.KEY_INDEX, root.getInt("sqn")); - position.set(Position.KEY_EVENT, root.getInt("reason")); - - if (root.containsKey("analogues")) { - JsonArray analogues = root.getJsonArray("analogues"); - for (int i = 0; i < analogues.size(); i++) { - JsonObject adc = analogues.getJsonObject(i); - position.set(Position.PREFIX_ADC + adc.getInt("id"), adc.getInt("val")); - } - } - - if (root.containsKey("inputs")) { - int input = root.getInt("inputs"); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - position.set(Position.KEY_INPUT, input); - } - if (root.containsKey("outputs")) { - position.set(Position.KEY_OUTPUT, root.getInt("outputs")); - } - if (root.containsKey("status")) { - position.set(Position.KEY_STATUS, root.getInt("status")); - } - - if (root.containsKey("counters")) { - JsonArray counters = root.getJsonArray("counters"); - for (int i = 0; i < counters.size(); i++) { - JsonObject counter = counters.getJsonObject(i); - switch (counter.getInt("id")) { - case 0: - position.set(Position.KEY_BATTERY, counter.getInt("val") * 0.001); - break; - case 1: - position.set(Position.KEY_BATTERY_LEVEL, counter.getInt("val") * 0.01); - break; - default: - position.set("counter" + counter.getInt("id"), counter.getInt("val")); - break; - } - - } - } - - return position; - } - } diff --git a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java index d509b3ec0..e882c2378 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java @@ -101,10 +101,6 @@ public class DolphinProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, point.getSatellites()); position.set(Position.KEY_HDOP, point.getHDOP()); - for (int j = 0; j < point.getIOListIDCount(); j++) { - position.set(Position.PREFIX_IO + point.getIOListIDValue(j), point.getIOListValue(j)); - } - positions.add(position); } diff --git a/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java b/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java deleted file mode 100644 index 388c97f85..000000000 --- a/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java +++ /dev/null @@ -1,44 +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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; - -public class Dsf22FrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 21) { - return null; - } - - int count = buf.getUnsignedByte(buf.readerIndex() + 4); - - int length = 2 + 2 + 1 + count * (4 + 4 + 4 + 1 + 2 + 1); - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } else { - return null; - } - } - -} diff --git a/src/main/java/org/traccar/protocol/Dsf22Protocol.java b/src/main/java/org/traccar/protocol/Dsf22Protocol.java deleted file mode 100644 index bffc3e419..000000000 --- a/src/main/java/org/traccar/protocol/Dsf22Protocol.java +++ /dev/null @@ -1,40 +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.protocol; - -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class Dsf22Protocol extends BaseProtocol { - - public Dsf22Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Dsf22FrameDecoder()); - pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java deleted file mode 100644 index d5a9df7bc..000000000 --- a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java +++ /dev/null @@ -1,90 +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.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.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class Dsf22ProtocolDecoder extends BaseProtocolDecoder { - - public Dsf22ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - - String id = ByteBufUtil.hexDump(buf.readSlice(2)); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(true); - position.setLatitude(buf.readInt()); - position.setLongitude(buf.readInt()); - position.setTime(new Date(946684800000L + buf.readUnsignedInt())); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.001); - - int status = buf.readUnsignedByte(); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); - position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 1)); - position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 4)); - position.set(Position.KEY_ALARM, BitUtil.check(status, 6) ? Position.ALARM_JAMMING : null); - position.set(Position.KEY_STATUS, status); - - positions.add(position); - - } - - if (channel != null) { - byte[] response = {0x01}; - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(response), remoteAddress)); - } - - return positions; - } - -} diff --git a/src/main/java/org/traccar/protocol/DualcamFrameDecoder.java b/src/main/java/org/traccar/protocol/DualcamFrameDecoder.java deleted file mode 100644 index 312d43f19..000000000 --- a/src/main/java/org/traccar/protocol/DualcamFrameDecoder.java +++ /dev/null @@ -1,49 +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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; - -public class DualcamFrameDecoder extends BaseFrameDecoder { - - private static final int MESSAGE_MINIMUM_LENGTH = 4; - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { - return null; - } - - int length; - if (buf.getUnsignedShort(buf.readerIndex()) == 0) { - length = 16; - } else { - length = 4 + buf.getUnsignedShort(buf.readerIndex() + 2); - } - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java deleted file mode 100644 index 04c4f2bd1..000000000 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ /dev/null @@ -1,34 +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.protocol; - -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class DualcamProtocol extends BaseProtocol { - - public DualcamProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new DualcamFrameDecoder()); - pipeline.addLast(new DualcamProtocolDecoder(DualcamProtocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java deleted file mode 100644 index c64b8171f..000000000 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ /dev/null @@ -1,123 +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.protocol; - -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; -import org.traccar.helper.BitUtil; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; - -public class DualcamProtocolDecoder extends BaseProtocolDecoder { - - public DualcamProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_INIT = 0; - public static final int MSG_START = 1; - public static final int MSG_RESUME = 2; - public static final int MSG_SYNC = 3; - public static final int MSG_DATA = 4; - public static final int MSG_COMPLETE = 5; - public static final int MSG_FILE_REQUEST = 8; - public static final int MSG_INIT_REQUEST = 9; - - private String uniqueId; - private int packetCount; - private int currentPacket; - private ByteBuf photo; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int type = buf.readUnsignedShort(); - - switch (type) { - case MSG_INIT: - buf.readUnsignedShort(); // protocol id - uniqueId = String.valueOf(buf.readLong()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); - long settings = buf.readUnsignedInt(); - if (channel != null && deviceSession != null) { - ByteBuf response = Unpooled.buffer(); - if (BitUtil.between(settings, 26, 28) > 0) { - response.writeShort(MSG_FILE_REQUEST); - String file = BitUtil.check(settings, 26) ? "%photof" : "%photor"; - response.writeShort(file.length()); - response.writeCharSequence(file, StandardCharsets.US_ASCII); - } else { - response.writeShort(MSG_COMPLETE); - } - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - break; - case MSG_START: - buf.readUnsignedShort(); // length - packetCount = buf.readInt(); - currentPacket = 1; - photo = Unpooled.buffer(); - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(MSG_RESUME); - response.writeShort(4); - response.writeInt(currentPacket); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - break; - case MSG_DATA: - buf.readUnsignedShort(); // length - photo.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, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); - } finally { - photo.release(); - photo = null; - } - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(MSG_INIT_REQUEST); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - return position; - } else { - currentPacket += 1; - } - break; - default: - break; - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 8fe12fe69..613710587 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -421,7 +421,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { ByteBuf content = Unpooled.buffer(); if (type == MSG_LOGIN) { content.writeInt((int) (System.currentTimeMillis() / 1000)); - content.writeShort(1); // protocol version + content.writeByte(1); // protocol version content.writeByte(0); // action mask } ByteBuf response = EelinkProtocolEncoder.encodeContent( diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index 0a12f781d..cc7f6e935 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java @@ -75,7 +75,7 @@ public class EsealProtocolDecoder extends BaseProtocolDecoder { case "Event-Door": return Position.ALARM_DOOR; case "Event-Shock": - return Position.ALARM_VIBRATION; + return Position.ALARM_SHOCK; case "Event-Drop": return Position.ALARM_FALL_DOWN; case "Event-Lock": diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 5f9326a61..70972f847 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -31,7 +31,6 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; -import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; @@ -75,37 +74,6 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); - private static final Pattern PATTERN_NEW = new PatternBuilder() - .text("$$") - .number("d+,") // length - .number("(d+),") // imei - .number("x+,") // index - .text("A03,") // type - .number("(d+)?,") // alarm - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+)|") // mcc - .number("(d+)|") // mnc - .number("(x+)|") // lac - .number("(x+),") // cid - .number("(d+.d+),") // battery - .number("(d+),") // battery level - .number("(x+),") // status - .groupBegin() - .text("0,") // gps location - .number("([AV]),") // validity - .number("(d+),") // speed - .number("(d+),") // satellites - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+)") // longitude - .or() - .text("1,") // wifi location - .expression("([^*]+)") // wifi - .groupEnd() - .text("*") - .number("xx") // checksum - .compile(); - private static final Pattern PATTERN_PHOTO = new PatternBuilder() .text("$$") .number("d+,") // length @@ -192,61 +160,6 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { return null; } - - private Object decodeLocationNew( - Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_NEW, 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, decodeAlarm(parser.nextInt())); - - position.setDeviceTime(parser.nextDateTime()); - - Network network = new Network(); - network.addCellTower(CellTower.from( - parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())); - - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.KEY_STATUS, parser.nextHexInt()); - - if (parser.hasNext(5)) { - - position.setValid(parser.next().equals("A")); - position.setFixTime(position.getDeviceTime()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - - } else { - - String[] points = parser.next().split("\\|"); - for (String point : points) { - String[] wifi = point.split(":"); - String mac = wifi[0].replaceAll("(..)", "$1:"); - network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), Integer.parseInt(wifi[1]))); - } - - } - - position.setNetwork(network); - - return position; - } - private Object decodeLocation( Channel channel, SocketAddress remoteAddress, String sentence) { @@ -293,12 +206,7 @@ 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))); - } else { - position.set("driverLicense", rfid); - } + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(parser.nextHexInt())); } if (parser.hasNext()) { @@ -388,10 +296,6 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { } } - } else if (type.equals("A03")) { - - return decodeLocationNew(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)); - } else { return decodeLocation(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)); diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 83ca74ce5..0a0d04db0 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -190,7 +190,7 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { return true; case "shock.event.trigger": if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); + position.set(Position.KEY_ALARM, Position.ALARM_SHOCK); } return true; case "overspeeding.event.trigger": diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java deleted file mode 100644 index bc6a49907..000000000 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ /dev/null @@ -1,37 +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.protocol; - -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class FlexApiProtocol extends BaseProtocol { - - public FlexApiProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(5120)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java deleted file mode 100644 index d4d539a9e..000000000 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ /dev/null @@ -1,101 +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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonObject; -import java.io.StringReader; -import java.net.SocketAddress; -import java.util.Date; - -public class FlexApiProtocolDecoder extends BaseProtocolDecoder { - - public FlexApiProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String message = (String) msg; - JsonObject root = Json.createReader(new StringReader(message.substring(1, message.length() - 2))).readObject(); - - String topic = root.getString("topic"); - String clientId = topic.substring(3, topic.indexOf('/', 3)); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, clientId); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - JsonObject payload = root.getJsonObject("payload"); - - if (topic.contains("gnss")) { - - position.setValid(true); - - if (payload.containsKey("time")) { - position.setTime(new Date(payload.getInt("time") * 1000L)); - position.setLatitude(payload.getJsonNumber("lat").doubleValue()); - position.setLongitude(payload.getJsonNumber("log").doubleValue()); - } else { - position.setTime(new Date(payload.getInt("gnss.ts") * 1000L)); - position.setLatitude(payload.getJsonNumber("gnss.latitude").doubleValue()); - position.setLongitude(payload.getJsonNumber("gnss.longitude").doubleValue()); - } - - position.setAltitude(payload.getJsonNumber("gnss.altitude").doubleValue()); - position.setSpeed(payload.getJsonNumber("gnss.speed").doubleValue()); - position.setCourse(payload.getJsonNumber("gnss.heading").doubleValue()); - - position.set(Position.KEY_SATELLITES, payload.getInt("gnss.num_sv")); - - } else if (topic.contains("obd")) { - - getLastLocation(position, new Date(payload.getInt("obd.ts") * 1000L)); - - if (payload.containsKey("obd.speed")) { - position.set(Position.KEY_OBD_SPEED, payload.getJsonNumber("obd.speed").doubleValue()); - } - if (payload.containsKey("obd.odo")) { - position.set(Position.KEY_OBD_ODOMETER, payload.getInt("obd.odo")); - } - if (payload.containsKey("obd.rpm")) { - position.set(Position.KEY_RPM, payload.getInt("obd.rpm")); - } - if (payload.containsKey("obd.vin")) { - position.set(Position.KEY_VIN, payload.getString("obd.vin")); - } - - } else { - - return 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..dc558147a 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -309,17 +309,18 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { Position position = null; - if (photo == null) { - photo = Unpooled.buffer(); - } - - buf.readUnsignedByte(); // part number - if (length > 1) { + if (photo == null) { + photo = Unpooled.buffer(); + } + + buf.readUnsignedByte(); // part number photo.writeBytes(buf, length - 1); - } else { + sendResponse(channel, 0x07, buf.readUnsignedShortLE()); + + } else if (photo != null) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); @@ -335,8 +336,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } - sendResponse(channel, 0x07, buf.readUnsignedShortLE()); - return position; } diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index a86249224..76278070e 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -187,12 +187,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { int index = 0; String[] fragments = sentence.split(","); - if (fragments[index].matches("[0-9]{12}")) { - position.setTime(new SimpleDateFormat("HHmmssddMMyy").parse(fragments[index++])); - } else { - getLastLocation(position, null); - position.set(Position.KEY_RESULT, fragments[index++]); - } + position.setTime(new SimpleDateFormat("HHmmssddMMyy").parse(fragments[index++])); for (; index < fragments.length; index += 1) { if (!fragments[index].isEmpty()) { diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index d74f19179..2ca71a1ae 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -140,6 +140,8 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_FUEL_LEAK; } switch (value) { + case "tracker": + return null; case "help me": return Position.ALARM_SOS; case "low battery": @@ -150,6 +152,10 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_MOVEMENT; case "speed": return Position.ALARM_OVERSPEED; + case "acc on": + return Position.ALARM_POWER_ON; + case "acc off": + return Position.ALARM_POWER_OFF; case "door alarm": return Position.ALARM_DOOR; case "ac alarm": @@ -157,14 +163,13 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { case "accident alarm": return Position.ALARM_ACCIDENT; case "sensor alarm": - return Position.ALARM_VIBRATION; + return Position.ALARM_SHOCK; case "bonnet alarm": return Position.ALARM_BONNET; case "footbrake alarm": return Position.ALARM_FOOT_BRAKE; case "DTC": return Position.ALARM_FAULT; - case "tracker": default: return null; } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 0dcdab892..281234ebb 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -56,7 +56,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LOGIN = 0x01; public static final int MSG_GPS = 0x10; - public static final int MSG_GPS_LBS_6 = 0x11; + public static final int MSG_LBS = 0x11; public static final int MSG_GPS_LBS_1 = 0x12; public static final int MSG_GPS_LBS_2 = 0x22; public static final int MSG_GPS_LBS_3 = 0x37; @@ -78,11 +78,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { 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_AZ735_GPS = 0x32; + public static final int MSG_AZ735_ALARM = 0x33; 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; @@ -123,12 +120,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_2: case MSG_GPS_LBS_3: case MSG_GPS_LBS_4: - case MSG_GPS_LBS_5: - case MSG_GPS_LBS_6: case MSG_GPS_LBS_STATUS_1: case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: - case MSG_GPS_LBS_STATUS_4: case MSG_GPS_PHONE: case MSG_GPS_LBS_EXTEND: case MSG_GPS_2: @@ -142,17 +136,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private static boolean hasLbs(int type) { switch (type) { + case MSG_LBS: case MSG_LBS_STATUS: case MSG_GPS_LBS_1: case MSG_GPS_LBS_2: case MSG_GPS_LBS_3: case MSG_GPS_LBS_4: - case MSG_GPS_LBS_5: - case MSG_GPS_LBS_6: case MSG_GPS_LBS_STATUS_1: case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: - case MSG_GPS_LBS_STATUS_4: case MSG_GPS_2: case MSG_FENCE_SINGLE: case MSG_FENCE_MULTI: @@ -171,7 +163,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_1: case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: - case MSG_GPS_LBS_STATUS_4: return true; default: return false; @@ -276,7 +267,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeLbs(Position position, ByteBuf buf, int type, boolean hasLength) { + private boolean decodeLbs(Position position, ByteBuf buf, boolean hasLength) { int length = 0; if (hasLength) { @@ -297,11 +288,10 @@ 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 = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); - position.setNetwork(new Network(CellTower.from(BitUtil.to(mcc, 15), mnc, lac, cid))); + position.setNetwork(new Network(CellTower.from( + BitUtil.to(mcc, 15), mnc, buf.readUnsignedShort(), buf.readUnsignedMedium()))); if (length > 9) { buf.skipBytes(length - 9); @@ -321,7 +311,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { switch (BitUtil.between(status, 3, 6)) { case 1: - position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); + position.set(Position.KEY_ALARM, Position.ALARM_SHOCK); break; case 2: position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); @@ -700,9 +690,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; // space10x multi-lbs message } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_EXTEND - || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { + || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3) { - boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5; + boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3; DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -713,9 +703,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mcc = buf.readUnsignedShort(); int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); Network network = new Network(); - - int cellCount = type == MSG_WIFI_5 ? 6 : 7; - for (int i = 0; i < cellCount; i++) { + for (int i = 0; i < 7; i++) { int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); int rssi = -buf.readUnsignedByte(); @@ -887,7 +875,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type)) { - decodeLbs(position, buf, type, hasStatus(type)); + decodeLbs(position, buf, hasStatus(type)); } if (hasStatus(type)) { @@ -1055,7 +1043,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, position.getDeviceTime()); } - if (decodeLbs(position, buf, type, true)) { + if (decodeLbs(position, buf, true)) { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } @@ -1143,7 +1131,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { - return decodeExtendedModular(channel, buf, deviceSession); + return decodeExtendedModular(buf, deviceSession); } else { @@ -1154,7 +1142,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession) { + private Object decodeExtendedModular(ByteBuf buf, DeviceSession deviceSession) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -1255,12 +1243,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - if (position.getFixTime() == null) { - getLastLocation(position, null); - } - - sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - return position; } diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java deleted file mode 100644 index 387b967d3..000000000 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ /dev/null @@ -1,38 +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.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; - -public class HoopoProtocol extends BaseProtocol { - - public HoopoProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new JsonFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new HoopoProtocolDecoder(HoopoProtocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java deleted file mode 100644 index 65333ba6e..000000000 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ /dev/null @@ -1,72 +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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonObject; -import java.io.StringReader; -import java.net.SocketAddress; -import java.time.OffsetDateTime; -import java.util.Date; - -public class HoopoProtocolDecoder extends BaseProtocolDecoder { - - public HoopoProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - JsonObject json = Json.createReader(new StringReader((String) msg)).readObject(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("deviceId")); - if (deviceSession == null) { - return null; - } - - if (json.containsKey("eventData")) { - - JsonObject eventData = json.getJsonObject("eventData"); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - Date time = new Date(OffsetDateTime.parse(json.getString("eventTime")).toInstant().toEpochMilli()); - position.setTime(time); - - position.setValid(true); - position.setLatitude(eventData.getJsonNumber("latitude").doubleValue()); - position.setLongitude(eventData.getJsonNumber("longitude").doubleValue()); - - position.set(Position.KEY_EVENT, eventData.getString("eventType")); - position.set(Position.KEY_BATTERY_LEVEL, eventData.getInt("batteryLevel")); - - return position; - - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 891046213..2e1ddf5f2 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -262,13 +262,6 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { case 0x0011: position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 0.05); break; - case 0x0014: - position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte() / 255.0); - position.set("timingAdvance", buf.readUnsignedByte() * 0.5); - position.set("airTemp", buf.readUnsignedByte() - 40); - position.set("airFlow", buf.readUnsignedShort() * 0.01); - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte() / 255.0); - break; case 0x0020: String[] cells = buf.readCharSequence( length, StandardCharsets.US_ASCII).toString().split("\\+"); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index aa85ea061..37d7ae718 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -53,14 +53,12 @@ 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_ACCELERATION = 0x2070; public static final int MSG_LOCATION_REPORT_2 = 0x5501; public static final int MSG_LOCATION_REPORT_BLIND = 0x5502; public static final int MSG_LOCATION_BATCH = 0x0704; public static final int MSG_OIL_CONTROL = 0XA006; 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 RESULT_SUCCESS = 0; @@ -73,7 +71,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { if (shortIndex) { buf.writeByte(1); } else { - buf.writeShort(0); + buf.writeShort(1); } buf.writeBytes(data); data.release(); @@ -137,11 +135,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return null; } - private int readSignedWord(ByteBuf buf) { - int value = buf.readUnsignedShort(); - return BitUtil.check(value, 15) ? -BitUtil.to(value, 15) : BitUtil.to(value, 15); - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -183,7 +176,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) { sendGeneralResponse(channel, remoteAddress, id, type, index); @@ -222,33 +215,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } - } else if (type == MSG_ACCELERATION) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - StringBuilder data = new StringBuilder("["); - while (buf.readableBytes() > 2) { - buf.skipBytes(6); // time - if (data.length() > 1) { - data.append(","); - } - data.append("["); - data.append(readSignedWord(buf)); - data.append(","); - data.append(readSignedWord(buf)); - data.append(","); - data.append(readSignedWord(buf)); - data.append("]"); - } - data.append("]"); - - position.set(Position.KEY_G_SENSOR, data.toString()); - - return position; - } return null; @@ -266,76 +232,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return null; } - private void decodeExtension(Position position, ByteBuf buf, int endIndex) { - while (buf.readerIndex() < endIndex) { - int type = buf.readUnsignedByte(); - int length = buf.readUnsignedByte(); - switch (type) { - case 0x01: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100L); - break; - case 0x02: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); - break; - case 0x03: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); - break; - case 0x80: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); - break; - case 0x81: - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - break; - case 0x82: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); - break; - case 0x83: - position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); - break; - case 0x84: - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); - break; - case 0x85: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort()); - break; - case 0x86: - position.set("intakeTemp", buf.readUnsignedByte() - 40); - break; - case 0x87: - position.set("intakeFlow", buf.readUnsignedShort()); - break; - case 0x88: - position.set("intakePressure", buf.readUnsignedByte()); - break; - case 0x89: - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); - break; - case 0x8B: - position.set(Position.KEY_VIN, buf.readCharSequence(17, StandardCharsets.US_ASCII).toString()); - break; - case 0x8C: - position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100L); - break; - case 0x8D: - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 1000L); - break; - case 0x8E: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); - break; - case 0xA0: - String codes = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); - position.set(Position.KEY_DTCS, codes.replace(',', ' ')); - break; - case 0xCC: - position.set(Position.KEY_ICCID, buf.readCharSequence(20, StandardCharsets.US_ASCII).toString()); - break; - default: - buf.skipBytes(length); - break; - } - } - } - private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { Position position = new Position(getProtocolName()); @@ -416,11 +312,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, Integer.parseInt(lockStatus.substring(2, 5)) * 0.01); } break; - case 0x80: - buf.readUnsignedByte(); // content - endIndex = buf.writerIndex() - 2; - decodeExtension(position, buf, endIndex); - break; case 0x91: position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); position.set(Position.KEY_RPM, buf.readUnsignedShort()); @@ -441,13 +332,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); } break; - case 0xA7: - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - break; - case 0xAC: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - break; case 0xD0: long userStatus = buf.readUnsignedInt(); if (BitUtil.check(userStatus, 3)) { @@ -505,16 +389,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } } break; - case 0xED: - String license = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString().trim(); - position.set("driverLicense", license); - break; - case 0xEE: - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; default: break; } @@ -576,15 +450,11 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { List<Position> positions = new LinkedList<>(); int count = buf.readUnsignedShort(); - int locationType = buf.readUnsignedByte(); + buf.readUnsignedByte(); // location type for (int i = 0; i < count; i++) { int endIndex = buf.readUnsignedShort() + buf.readerIndex(); - Position position = decodeLocation(deviceSession, buf); - if (locationType > 0) { - position.set(Position.KEY_ARCHIVE, true); - } - positions.add(position); + positions.add(decodeLocation(deviceSession, buf)); buf.readerIndex(endIndex); } diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index dc4bd3486..d745153a4 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 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { } static boolean isLongFormat(ByteBuf buf, int flagIndex) { - return buf.getUnsignedByte(flagIndex) >> 4 >= 7; + return buf.getUnsignedByte(flagIndex) >> 4 == 0x7; } static void decodeBinaryLocation(ByteBuf buf, Position position) { @@ -141,8 +141,6 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { int version = BitUtil.from(buf.readUnsignedByte(), 4); buf.readUnsignedShort(); // length - boolean responseRequired = false; - while (buf.readableBytes() > 1) { Position position = new Position(getProtocolName()); @@ -162,9 +160,6 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, BitUtil.check(status, 2) ? Position.ALARM_GEOFENCE_EXIT : null); position.set(Position.KEY_ALARM, BitUtil.check(status, 3) ? Position.ALARM_POWER_CUT : null); position.set(Position.KEY_ALARM, BitUtil.check(status, 4) ? Position.ALARM_VIBRATION : null); - if (BitUtil.check(status, 5)) { - responseRequired = true; - } position.set(Position.KEY_BLOCKED, BitUtil.check(status, 7)); position.set(Position.KEY_ALARM, BitUtil.check(status, 8 + 3) ? Position.ALARM_LOW_BATTERY : null); position.set(Position.KEY_ALARM, BitUtil.check(status, 8 + 6) ? Position.ALARM_FAULT : null); @@ -181,7 +176,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { cellTower.setSignalStrength((int) buf.readUnsignedByte()); position.setNetwork(new Network(cellTower)); - if (protocolVersion == 0x17 || protocolVersion == 0x19) { + if (protocolVersion == 0x17) { buf.readUnsignedByte(); // geofence id buf.skipBytes(3); // reserved buf.skipBytes(buf.readableBytes() - 1); @@ -237,15 +232,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { } - int index = buf.readUnsignedByte(); - - if (channel != null && responseRequired) { - if (protocolVersion < 0x19) { - channel.writeAndFlush(new NetworkMessage("(P35)", remoteAddress)); - } else { - channel.writeAndFlush(new NetworkMessage("(P69,0," + index + ")", remoteAddress)); - } - } + buf.readUnsignedByte(); // index return positions; } diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 45890e9a2..4abb75025 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -93,7 +93,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { case "H": return Position.ALARM_POWER_OFF; case "8": - return Position.ALARM_VIBRATION; + return Position.ALARM_SHOCK; case "7": case "4": return Position.ALARM_GEOFENCE_EXIT; diff --git a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java index 7233280c2..e63dd3b32 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java @@ -423,7 +423,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { case "psr": return Position.ALARM_POWER_RESTORED; case "hit": - return Position.ALARM_VIBRATION; + return Position.ALARM_SHOCK; case "belt on": case "belton": return Position.ALARM_LOCK; diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 0eb6f8776..9b12f1c15 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 - 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. @@ -23,7 +23,6 @@ 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.Checksum; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -69,23 +68,15 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // runtime .number("(d+)|") // mcc .number("(d+)|") // mnc - .number("(x+)?|") // lac - .number("(x+)?,") // cid + .number("(x+)|") // lac + .number("(x+),") // cid .number("(xx)") // input .number("(xx),") // output - .groupBegin() - .number("(d+.d+)|") // battery - .number("(d+.d+)|") // power - .number("d+.d+|") // rtc voltage - .number("d+.d+|") // mcu voltage - .number("d+.d+,") // gps voltage - .or() .number("(x+)?|") // adc1 .number("(x+)?|") // adc2 .number("(x+)?|") // adc3 .number("(x+)|") // battery .number("(x+)?,") // power - .groupEnd() .groupBegin() .expression("([^,]+)?,").optional() // event specific .expression("[^,]*,") // reserved @@ -183,70 +174,51 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextInt()); position.set("runtime", parser.next()); - int mcc = parser.nextInt(); - int mnc = parser.nextInt(); - int lac = parser.nextHexInt(0); - int cid = parser.nextHexInt(0); - if (mcc != 0 && mnc != 0) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid, rssi))); - } - - int input = parser.nextHexInt(); - int output = parser.nextHexInt(); - - position.set(Position.KEY_IGNITION, BitUtil.check(input, 2)); + position.setNetwork(new Network(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), rssi))); - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); - - if (parser.hasNext(2)) { - - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_POWER, parser.nextDouble()); - - } else { - - for (int i = 1; i <= 3; i++) { - position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); - } + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_OUTPUT, parser.nextHexInt()); - String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); - if (deviceModel == null) { - deviceModel = ""; - } - 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_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_POWER, parser.nextHexInt(0)); - break; - case "T1": - case "T3": - case "MVT100": - case "MVT600": - case "MVT800": - case "TC68": - case "TC68S": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 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; - default: - position.set(Position.KEY_BATTERY, parser.nextHexInt(0)); - position.set(Position.KEY_POWER, parser.nextHexInt(0)); - break; - } + for (int i = 1; i <= 3; i++) { + position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); + } + String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); + if (deviceModel == null) { + deviceModel = ""; + } + 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_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_POWER, parser.nextHexInt(0)); + break; + case "T1": + case "T3": + case "MVT100": + case "MVT600": + case "MVT800": + case "TC68": + case "TC68S": + position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 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; + default: + position.set(Position.KEY_BATTERY, parser.nextHexInt(0)); + position.set(Position.KEY_POWER, parser.nextHexInt(0)); + break; } String eventData = parser.next(); diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java index d5be31cec..2b7a960c4 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 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. @@ -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("![3A-D],.*")) { return null; } @@ -161,19 +161,6 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type.equals("5")) { - - String[] values = sentence.split(","); - - getLastLocation(position, null); - - position.set(Position.KEY_RSSI, Integer.parseInt(values[1])); - if (values.length >= 4) { - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[3])); - } - - return position; - } else if (type.equals("B") || type.equals("D")) { Parser parser = new Parser(PATTERN_BD, sentence); diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 641a45864..059041d6b 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -124,14 +124,6 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { } } - private String readTagId(ByteBuf buf) { - StringBuilder tagId = new StringBuilder(); - for (int i = 0; i < 6; i++) { - tagId.insert(0, ByteBufUtil.hexDump(buf.readSlice(1))); - } - return tagId.toString(); - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -222,7 +214,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { } break; case 0x23: - position.set("tagId", readTagId(buf)); + position.set("tagId", ByteBufUtil.hexDump(buf.readSlice(6))); position.setLatitude(buf.readIntLE() * 0.0000001); position.setLongitude(buf.readIntLE() * 0.0000001); position.setValid(true); @@ -236,9 +228,9 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { break; case 0x28: int beaconFlags = buf.readUnsignedByte(); - position.set("tagId", readTagId(buf)); - position.set("tagRssi", (int) buf.readByte()); - position.set("tag1mRssi", (int) buf.readByte()); + position.set("tagId", ByteBufUtil.hexDump(buf.readSlice(6))); + position.set("tagRssi", buf.readUnsignedByte()); + buf.readUnsignedByte(); // 1m rssi if (BitUtil.check(beaconFlags, 7)) { position.setLatitude(buf.readIntLE() * 0.0000001); position.setLongitude(buf.readIntLE() * 0.0000001); diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index 28380a2af..ebf2c9c7f 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocol.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2021 Anton Tananaev (anton@traccar.org) + * 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. @@ -28,7 +28,7 @@ public class MobilogixProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ']')); + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]\r\n", "]")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MobilogixProtocolDecoder(MobilogixProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index 86c89e336..8677ba9ec 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2021 Anton Tananaev (anton@traccar.org) + * 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. @@ -39,52 +39,28 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { .text("[") .number("(dddd)-(dd)-(dd) ") // date (yyyymmdd) .number("(dd):(dd):(dd),") // time (hhmmss) - .number("Td+,") // type - .number("(d),") // archive + .number("Td,") // type + .number("d+,") // device type .expression("[^,]+,") // protocol version .expression("([^,]+),") // serial number .number("(xx),") // status - .number("(d+.d+)") // battery - .groupBegin() - .text(",") - .number("(d)") // satellites + .number("(d+.d+),") // battery + .number("(d)") // valid .number("(d)") // rssi - .number("(d),") // valid + .number("(d),") // satellites .number("(-?d+.d+),") // latitude .number("(-?d+.d+),") // longitude .number("(d+.?d*),") // speed .number("(d+.?d*)") // course - .groupEnd("?") .any() .compile(); - private String decodeAlarm(String type) { - switch (type) { - case "T8": - return Position.ALARM_LOW_BATTERY; - case "T9": - return Position.ALARM_VIBRATION; - case "T10": - return Position.ALARM_POWER_CUT; - case "T11": - return Position.ALARM_LOW_POWER; - case "T12": - return Position.ALARM_GEOFENCE_EXIT; - case "T13": - return Position.ALARM_OVERSPEED; - case "T15": - return Position.ALARM_TOW; - default: - return null; - } - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String sentence = ((String) msg).trim(); - String type = sentence.substring(21, sentence.indexOf(',', 21)); + String sentence = (String) msg; + String type = sentence.substring(21, 21 + 2); if (channel != null) { String time = sentence.substring(1, 20); @@ -92,22 +68,19 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { if (type.equals("T1")) { response = String.format("[%s,S1,1]", time); } else { - response = String.format("[%s,S%s]", time, type.substring(1)); + response = String.format("[%s,S%c]", time, type.charAt(1)); } channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - Parser parser = new Parser(PATTERN, sentence); + Parser parser = new Parser(PATTERN, (String) msg); if (!parser.matches()) { return null; } Position position = new Position(getProtocolName()); - position.setDeviceTime(parser.nextDateTime()); - if (parser.nextInt() == 0) { - position.set(Position.KEY_ARCHIVE, true); - } + position.setTime(parser.nextDateTime()); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { @@ -115,9 +88,6 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_TYPE, type); - position.set(Position.KEY_ALARM, decodeAlarm(type)); - int status = parser.nextHexInt(); position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); position.set(Position.KEY_MOTION, BitUtil.check(status, 3)); @@ -125,24 +95,15 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextDouble()); - if (parser.hasNext(7)) { + position.setValid(parser.nextInt() > 0); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_RSSI, 6 * parser.nextInt() - 111); + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setValid(parser.nextInt() > 0); - position.setFixTime(position.getDeviceTime()); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - - } else { - - getLastLocation(position, position.getDeviceTime()); - - } + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); return position; } diff --git a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java index 379b610e1..7bde85f87 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -97,10 +97,6 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { long date = buf.readUnsignedIntLE(); long days = BitUtil.from(date, 6 + 6 + 5); - if (days < 7 * 780) { - days += 7 * 1024; - } - long hours = BitUtil.between(date, 6 + 6, 6 + 6 + 5); long minutes = BitUtil.between(date, 6, 6 + 6); long seconds = BitUtil.to(date, 6); diff --git a/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java deleted file mode 100644 index 0fb82528b..000000000 --- a/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java +++ /dev/null @@ -1,75 +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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; -import org.traccar.BasePipelineFactory; - -import java.nio.charset.StandardCharsets; -import java.util.BitSet; - -public class NavtelecomFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.getByte(buf.readerIndex()) == '@') { - - int length = buf.getUnsignedShortLE(12) + 12 + 2 + 2; - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - } else { - - NavtelecomProtocolDecoder protocolDecoder = - BasePipelineFactory.getHandler(ctx.pipeline(), NavtelecomProtocolDecoder.class); - if (protocolDecoder == null) { - throw new RuntimeException("Decoder not found"); - } - - String type = buf.getCharSequence(buf.readerIndex(), 2, StandardCharsets.US_ASCII).toString(); - BitSet bits = protocolDecoder.getBits(); - - if (type.equals("~A")) { - int count = buf.getUnsignedByte(buf.readerIndex() + 2); - int length = 2 + 1 + 1; - - for (int i = 0; i < count; i++) { - for (int j = 0; j < bits.length(); j++) { - if (bits.get(j)) { - length += NavtelecomProtocolDecoder.getItemLength(j + 1); - } - } - } - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - } else { - throw new UnsupportedOperationException("Unsupported message type: " + type); - } - - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index 29ce8c41e..29ad62e48 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -15,17 +15,20 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import java.nio.ByteOrder; + public class NavtelecomProtocol extends BaseProtocol { public NavtelecomProtocol() { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new NavtelecomFrameDecoder()); + pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 12, 2, 2, 0, true)); pipeline.addLast(new NavtelecomProtocolDecoder(NavtelecomProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index bdcc12c4c..2362b1870 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -19,22 +19,12 @@ 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.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 java.net.SocketAddress; import java.nio.charset.StandardCharsets; -import java.util.BitSet; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { @@ -42,210 +32,36 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Map<Integer, Integer> ITEM_LENGTH_MAP = new HashMap<>(); - - static { - int[] l1 = { - 4, 5, 6, 7, 8, 29, 30, 31, 32, 45, 46, 47, 48, 49, 50, 51, 52, 56, 63, 64, 65, 69, 72, 78, 79, 80, 81, - 82, 83, 98, 99, 101, 104, 118, 122, 123, 124, 125, 126, 139, 140, 144, 145, 167, 168, 169, 170, 199, - 202, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222 - }; - int[] l2 = { - 2, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 35, 36, 38, 39, 40, 41, 42, 43, 44, 53, 55, 58, - 59, 60, 61, 62, 66, 68, 71, 75, 100, 106, 108, 110, 111, 112, 113, 114, 115, 116, 117, 119, 120, 121, - 133, 134, 135, 136, 137, 138, 141, 143, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 171, 175, 177, 178, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 200, 201, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237 - }; - int[] l3 = { - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 142, 146, 198 - }; - int[] l4 = { - 1, 3, 9, 10, 11, 12, 13, 15, 16, 33, 34, 37, 54, 57, 67, 74, 76, 102, 103, 105, 127, 128, 129, 130, 131, - 132, 172, 173, 174, 176, 179, 193, 194, 195, 196, 203, 205, 206, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252 - }; - for (int i : l1) { - ITEM_LENGTH_MAP.put(i, 1); - } - for (int i : l2) { - ITEM_LENGTH_MAP.put(i, 2); - } - for (int i : l3) { - ITEM_LENGTH_MAP.put(i, 3); - } - for (int i : l4) { - ITEM_LENGTH_MAP.put(i, 4); - } - ITEM_LENGTH_MAP.put(70, 8); - ITEM_LENGTH_MAP.put(73, 16); - ITEM_LENGTH_MAP.put(77, 37); - ITEM_LENGTH_MAP.put(94, 6); - ITEM_LENGTH_MAP.put(95, 12); - ITEM_LENGTH_MAP.put(96, 24); - ITEM_LENGTH_MAP.put(97, 48); - ITEM_LENGTH_MAP.put(107, 6); - ITEM_LENGTH_MAP.put(109, 6); - ITEM_LENGTH_MAP.put(197, 6); - ITEM_LENGTH_MAP.put(204, 5); - ITEM_LENGTH_MAP.put(253, 8); - ITEM_LENGTH_MAP.put(254, 8); - ITEM_LENGTH_MAP.put(255, 8); - } - - private BitSet bits; - - public static int getItemLength(int id) { - Integer length = ITEM_LENGTH_MAP.get(id); - if (length == null) { - throw new IllegalArgumentException(String.format("Unknown item: %d", id)); - } - return length; - } - - public BitSet getBits() { - return bits; - } - - private void sendResponse( - Channel channel, SocketAddress remoteAddress, int receiver, int sender, ByteBuf content) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeCharSequence("@NTC", StandardCharsets.US_ASCII); - response.writeIntLE(sender); - response.writeIntLE(receiver); - response.writeShortLE(content.readableBytes()); - response.writeByte(Checksum.xor(content.nioBuffer())); - response.writeByte(Checksum.xor(response.nioBuffer())); - response.writeBytes(content); - content.release(); - - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; - if (buf.getByte(buf.readerIndex()) == '@') { - - buf.skipBytes(4); // preamble - int receiver = buf.readIntLE(); - int sender = buf.readIntLE(); - int length = buf.readUnsignedShortLE(); - buf.readUnsignedByte(); // data checksum - buf.readUnsignedByte(); // header checksum - - String type = buf.toString(buf.readerIndex(), 6, StandardCharsets.US_ASCII); - - if (type.startsWith("*>S")) { + buf.skipBytes(4); // preamble + int receiver = buf.readIntLE(); + int sender = buf.readIntLE(); + int length = buf.readUnsignedShortLE(); + buf.readUnsignedByte(); // data checksum + buf.readUnsignedByte(); // header checksum - String sentence = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); - getDeviceSession(channel, remoteAddress, sentence.substring(4)); + String sentence = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); - ByteBuf payload = Unpooled.copiedBuffer("*<S", StandardCharsets.US_ASCII); + if (sentence.startsWith("*>S")) { - sendResponse(channel, remoteAddress, receiver, sender, payload); + String data = "*<S"; - } else if (type.startsWith("*>FLEX")) { - - buf.skipBytes(6); - - ByteBuf payload = Unpooled.buffer(); - payload.writeCharSequence("*<FLEX", StandardCharsets.US_ASCII); - payload.writeByte(buf.readUnsignedByte()); // protocol - payload.writeByte(buf.readUnsignedByte()); // protocol version - payload.writeByte(buf.readUnsignedByte()); // struct version - - int bitCount = buf.readUnsignedByte(); - bits = new BitSet((bitCount + 7) / 8); - - int currentByte = 0; - for (int i = 0; i < bitCount; i++) { - if (i % 8 == 0) { - currentByte = buf.readUnsignedByte(); - } - bits.set(i, BitUtil.check(currentByte, 7 - i % 8)); - } - - sendResponse(channel, remoteAddress, receiver, sender, payload); - - } - - } else { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - String type = buf.readCharSequence(2, StandardCharsets.US_ASCII).toString(); - - if (type.equals("~A")) { - - int count = buf.readUnsignedByte(); - List<Position> positions = new LinkedList<>(); - - for (int i = 0; i < count; i++) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - for (int j = 0; j < bits.length(); j++) { - if (bits.get(j)) { - switch (j + 1) { - case 1: - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - break; - case 2: - position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); - break; - case 3: - position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); - break; - case 9: - position.setValid(true); - position.setFixTime(new Date(buf.readUnsignedIntLE() * 1000)); - break; - case 10: - position.setLatitude(buf.readIntLE() * 0.0001 / 60); - break; - case 11: - position.setLongitude(buf.readIntLE() * 0.0001 / 60); - break; - case 12: - position.setAltitude(buf.readIntLE() * 0.1); - break; - case 13: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); - break; - default: - buf.skipBytes(getItemLength(j + 1)); - break; - } - } - } - - if (position.getFixTime() == null) { - getLastLocation(position, position.getDeviceTime()); - } - - positions.add(position); - } - - int checksum = buf.readUnsignedByte(); - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeCharSequence(type, StandardCharsets.US_ASCII); - response.writeByte(count); - response.writeByte(checksum); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - return positions; + ByteBuf response = Unpooled.buffer(); + response.writeCharSequence("@NTC", StandardCharsets.US_ASCII); + response.writeIntLE(sender); + response.writeIntLE(receiver); + response.writeShortLE(data.length()); + response.writeByte(Checksum.xor(data)); + response.writeByte(Checksum.xor(response.nioBuffer())); + response.writeCharSequence(data, StandardCharsets.US_ASCII); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } diff --git a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java index e1847a2b2..ebb93abd6 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java @@ -80,15 +80,7 @@ public class PortmanProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, parser.next()); position.set(Position.KEY_STATUS, parser.nextHexLong()); position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - int event = parser.nextInt(); - position.set(Position.KEY_EVENT, event); - if (event == 253) { - position.set(Position.KEY_IGNITION, true); - } else if (event == 254) { - position.set(Position.KEY_IGNITION, false); - } - + position.set(Position.KEY_EVENT, parser.nextInt()); position.set(Position.KEY_SATELLITES, parser.nextInt()); position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_RSSI, parser.nextInt()); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 2812d22ff..5c2885a8b 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -102,12 +102,6 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { 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; - case 30: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); - break; case 74: position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; @@ -116,19 +110,22 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 80: position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); break; - case 134: + case 198: + if (readValue(buf, length, false) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } + break; + case 199: + case 200: if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } break; - case 136: + case 201: if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); } break; - case 197: - position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); - break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); break; diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 7a6b6f4fe..82f0e4061 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -150,21 +150,9 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { continue; } switch (dataTags[i]) { - case "#ALT#": - case "#ALTD#": - position.setAltitude(Double.parseDouble(data[i])); - break; - case "#DAL#": - case "#DID#": - position.set(Position.KEY_DRIVER_UNIQUE_ID, data[i]); - break; case "#EDT#": position.setDeviceTime(dateFormat.parse(data[i])); break; - case "#EDV1#": - case "#EDV2#": - position.set("external" + dataTags[i].charAt(4), data[i]); - break; case "#EID#": event = Integer.parseInt(data[i]); position.set(Position.KEY_ALARM, decodeAlarm(event)); @@ -178,9 +166,6 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { case "#EDSC#": position.set("reason", data[i]); break; - case "#IARM#": - position.set(Position.KEY_ARMED, Integer.parseInt(data[i]) > 0); - break; case "#PDT#": position.setFixTime(dateFormat.parse(data[i])); break; @@ -200,15 +185,11 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { position.setCourse(Integer.parseInt(data[i])); break; case "#ODO#": - case "#ODOD#": position.set(Position.KEY_ODOMETER, (long) (Double.parseDouble(data[i]) * 1000)); break; case "#BATC#": position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(data[i])); break; - case "#BATH#": - position.set("batteryHealth", Integer.parseInt(data[i])); - break; case "#TVI#": position.set(Position.KEY_DEVICE_TEMP, Double.parseDouble(data[i])); break; @@ -236,9 +217,6 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { case "#OUTD#": position.set(Position.PREFIX_OUT + (dataTags[i].charAt(4) - 'A' + 1), Integer.parseInt(data[i])); break; - case "#PDOP#": - position.set(Position.KEY_PDOP, Double.parseDouble(data[i])); - break; case "#LAC#": if (!data[i].isEmpty()) { lac = Integer.parseInt(data[i]); @@ -263,23 +241,18 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { break; case "#IGN#": case "#IGNL#": + position.set(Position.KEY_IGNITION, data[i].equals("1")); + break; case "#ENG#": - position.set(Position.KEY_IGNITION, Integer.parseInt(data[i]) > 0); + position.set("engine", data[i].equals("1")); break; case "#DUR#": case "#TDUR#": position.set(Position.KEY_HOURS, Integer.parseInt(data[i])); break; - case "#SAT#": - case "#SATN#": - position.set(Position.KEY_SATELLITES_VISIBLE, Integer.parseInt(data[i])); - break; case "#SATU#": position.set(Position.KEY_SATELLITES, Integer.parseInt(data[i])); break; - case "#STRT#": - position.set("starter", Double.parseDouble(data[i])); - break; case "#TS1#": position.set("sensor1State", Integer.parseInt(data[i])); break; diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 042518cb2..aae764993 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -77,10 +77,9 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .text(",") .number("d,") // extended .expression("([^,]+)?,") // fuel - .expression("([^,]+)?,?") // temperature + .expression("([^,]+)?") // temperature .groupEnd("?") .groupEnd("?") - .any() .compile(); private String decodeAlarm(int value) { @@ -169,12 +168,8 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), parser.nextInt()))); position.set(Position.KEY_STATUS, parser.nextHexInt()); - - int input = parser.nextHexInt(); - int output = parser.nextHexInt(); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 1)); - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_OUTPUT, parser.nextHexInt()); position.set(Position.KEY_POWER, parser.nextHexInt() * 0.01); position.set(Position.KEY_BATTERY, parser.nextHexInt() * 0.01); diff --git a/src/main/java/org/traccar/protocol/JsonFrameDecoder.java b/src/main/java/org/traccar/protocol/StbFrameDecoder.java index b2d7fbd53..6a4157f17 100644 --- a/src/main/java/org/traccar/protocol/JsonFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/StbFrameDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import org.traccar.BaseFrameDecoder; -public class JsonFrameDecoder extends BaseFrameDecoder { +public class StbFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index 002ed86c7..ca95787d0 100644 --- a/src/main/java/org/traccar/protocol/StbProtocol.java +++ b/src/main/java/org/traccar/protocol/StbProtocol.java @@ -27,7 +27,7 @@ public class StbProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new JsonFrameDecoder()); + pipeline.addLast(new StbFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StbProtocolDecoder(StbProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index cc985d605..bd151c604 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -26,7 +26,9 @@ 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 java.io.StringReader; import java.net.SocketAddress; @@ -95,34 +97,39 @@ public class StbProtocolDecoder extends BaseProtocolDecoder { String id = propertyObject.getString("id"); switch (id) { case "01101001": - locationType = Integer.parseInt(propertyObject.getString("value")); + locationType = propertyObject.getInt("value"); break; case "01102001": - position.setLongitude( - Double.parseDouble(propertyObject.getString("value"))); + position.setLongitude(propertyObject.getJsonNumber("value").doubleValue()); break; case "01103001": - position.setLatitude( - Double.parseDouble(propertyObject.getString("value"))); + position.setLatitude(propertyObject.getJsonNumber("value").doubleValue()); break; case "01118001": - position.set( - Position.KEY_DEVICE_TEMP, Double.parseDouble(propertyObject.getString("value"))); + position.set(Position.KEY_DEVICE_TEMP, propertyObject.getJsonNumber("value").doubleValue()); break; case "01122001": - position.set( - "batteryControl", Integer.parseInt(propertyObject.getString("value"))); + position.set("batteryControl", propertyObject.getInt("value")); break; case "02301001": - position.set( - "switchCabinetCommand", Integer.parseInt(propertyObject.getString("value"))); + position.set("switchCabinetCommand", propertyObject.getInt("value")); break; default: String key = "id" + id; if (propertyObject.containsKey("doorId")) { key += "Door" + propertyObject.getString("doorId"); } - position.set(key, propertyObject.getString("value")); + JsonValue value = propertyObject.get("value"); + switch (value.getValueType()) { + case STRING: + position.set(key, ((JsonString) value).getString()); + break; + case NUMBER: + position.set(key, ((JsonNumber) value).doubleValue()); + break; + default: + break; + } break; } } diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 21d23c24d..e13483449 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -171,7 +171,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { case 7: return Position.ALARM_MOVEMENT; case 8: - return Position.ALARM_VIBRATION; + return Position.ALARM_SHOCK; default: return null; } @@ -188,7 +188,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { case 14: return Position.ALARM_LOW_BATTERY; case 15: - return Position.ALARM_VIBRATION; + return Position.ALARM_SHOCK; case 16: return Position.ALARM_ACCIDENT; case 40: @@ -462,7 +462,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")) { return null; } @@ -475,12 +475,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_TYPE, type); - int mask; - if (type.equals("BLE")) { - mask = 0b1100000110110; - } else { - mask = Integer.parseInt(values[index++], 16); - } + int mask = Integer.parseInt(values[index++], 16); if (BitUtil.check(mask, 1)) { index += 1; // model @@ -529,83 +524,63 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(Double.parseDouble(values[index++])); } - if (type.equals("BLE")) { + if (BitUtil.check(mask, 13)) { + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + } - position.setValid(true); + if (BitUtil.check(mask, 14)) { + position.setCourse(Double.parseDouble(values[index++])); + } - int count = Integer.parseInt(values[index++]); + if (BitUtil.check(mask, 15)) { + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + } - for (int i = 1; i <= count; i++) { - position.set("tag" + i + "Rssi", Integer.parseInt(values[index++])); - index += 1; // rssi min - index += 1; // rssi max - position.set("tag" + i + "Id", values[index++]); - position.set("tag" + i + "Samples", Integer.parseInt(values[index++])); - position.set("tag" + i + "Major", Integer.parseInt(values[index++])); - position.set("tag" + i + "Minor", Integer.parseInt(values[index++])); - } + if (BitUtil.check(mask, 16)) { + position.setValid(values[index++].equals("1")); + } - } else { + if (BitUtil.check(mask, 17)) { + position.set(Position.KEY_INPUT, Integer.parseInt(values[index++])); + } - if (BitUtil.check(mask, 13)) { - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - } + if (BitUtil.check(mask, 18)) { + position.set(Position.KEY_OUTPUT, Integer.parseInt(values[index++])); + } - if (BitUtil.check(mask, 14)) { - position.setCourse(Double.parseDouble(values[index++])); + if (type.equals("ALT")) { + if (BitUtil.check(mask, 19)) { + position.set("alertId", values[index++]); } - - if (BitUtil.check(mask, 15)) { - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + if (BitUtil.check(mask, 20)) { + position.set("alertModifier", values[index++]); } - - if (BitUtil.check(mask, 16)) { - position.setValid(values[index++].equals("1")); + if (BitUtil.check(mask, 21)) { + position.set("alertData", values[index++]); } - - if (BitUtil.check(mask, 17)) { - position.set(Position.KEY_INPUT, Integer.parseInt(values[index++])); + } else { + if (BitUtil.check(mask, 19)) { + position.set("mode", Integer.parseInt(values[index++])); } - - if (BitUtil.check(mask, 18)) { - position.set(Position.KEY_OUTPUT, Integer.parseInt(values[index++])); + if (BitUtil.check(mask, 20)) { + position.set("reason", Integer.parseInt(values[index++])); } - - if (type.equals("ALT")) { - if (BitUtil.check(mask, 19)) { - position.set("alertId", values[index++]); - } - if (BitUtil.check(mask, 20)) { - position.set("alertModifier", values[index++]); - } - if (BitUtil.check(mask, 21)) { - position.set("alertData", values[index++]); - } - } else { - if (BitUtil.check(mask, 19)) { - position.set("mode", Integer.parseInt(values[index++])); - } - if (BitUtil.check(mask, 20)) { - position.set("reason", Integer.parseInt(values[index++])); - } - if (BitUtil.check(mask, 21)) { - position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); - } + if (BitUtil.check(mask, 21)) { + position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); } + } - if (BitUtil.check(mask, 22)) { - index += 1; // reserved - } + if (BitUtil.check(mask, 22)) { + index += 1; // reserved + } - if (BitUtil.check(mask, 23)) { - int assignMask = Integer.parseInt(values[index++], 16); - for (int i = 0; i <= 30; i++) { - if (BitUtil.check(assignMask, i)) { - position.set(Position.PREFIX_IO + (i + 1), values[index++]); - } + if (BitUtil.check(mask, 23)) { + int assignMask = Integer.parseInt(values[index++], 16); + for (int i = 0; i <= 30; i++) { + if (BitUtil.check(assignMask, i)) { + position.set(Position.PREFIX_IO + (i + 1), values[index++]); } } - } return position; diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index b15688df0..72b277c8c 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -58,8 +58,6 @@ 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_GPS_2 = 0x13; - public static final int MSG_ALARM_2 = 0x14; public static final int MSG_COMMAND = 0x81; private void sendResponse(Channel channel, short header, int type, int index, ByteBuf imei, int alarm) { @@ -77,7 +75,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeAlarm1(int value) { + private String decodeAlarm(int value) { switch (value) { case 1: return Position.ALARM_POWER_CUT; @@ -107,28 +105,6 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeAlarm2(int value) { - switch (value) { - case 1: - case 4: - return Position.ALARM_REMOVING; - case 2: - return Position.ALARM_TAMPERING; - case 3: - return Position.ALARM_SOS; - case 5: - return Position.ALARM_FALL_DOWN; - case 6: - return Position.ALARM_LOW_BATTERY; - case 14: - return Position.ALARM_GEOFENCE_ENTER; - case 15: - return Position.ALARM_GEOFENCE_EXIT; - default: - return null; - } - } - private Date readDate(ByteBuf buf) { return new DateBuilder() .setYear(BcdUtil.readInteger(buf, 2)) @@ -158,12 +134,11 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } - boolean positionType = type == MSG_GPS || type == MSG_GPS_2 || type == MSG_ALARM || type == MSG_ALARM_2; - if (!positionType) { + if (type != MSG_GPS && type != MSG_ALARM) { sendResponse(channel, header, type, index, imei, 0); } - if (positionType) { + if (type == MSG_GPS || type == MSG_ALARM) { return decodePosition(channel, deviceSession, buf, type, index, imei); @@ -254,11 +229,6 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } - private double decodeBleTemp(ByteBuf buf) { - int value = buf.readUnsignedShort(); - return (BitUtil.check(value, 15) ? -BitUtil.to(value, 15) : BitUtil.to(value, 15)) * 0.01; - } - private Position decodeBle( Channel channel, DeviceSession deviceSession, ByteBuf buf, int type, int index, ByteBuf imei) { @@ -308,7 +278,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level - position.set("tag" + i + "Temp", decodeBleTemp(buf)); + position.set("tag" + i + "Temp", buf.readUnsignedShort() * 0.01); position.set("tag" + i + "Humidity", buf.readUnsignedShort() * 0.01); position.set("tag" + i + "LightSensor", buf.readUnsignedShort()); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); @@ -317,7 +287,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level - position.set("tag" + i + "Temp", decodeBleTemp(buf)); + position.set("tag" + i + "Temp", buf.readUnsignedShort() * 0.01); position.set("tag" + i + "Door", buf.readUnsignedByte() > 0); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); break; @@ -373,19 +343,12 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("ac", BitUtil.check(io, 13)); position.set(Position.PREFIX_IN + 3, BitUtil.check(io, 12)); position.set(Position.PREFIX_IN + 4, BitUtil.check(io, 11)); - - if (type == MSG_GPS_2 || type == MSG_ALARM_2) { - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - buf.readUnsignedByte(); // reserved - } else { - position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 7)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 8)); - position.set(Position.PREFIX_OUT + 3, BitUtil.check(io, 9)); - } + position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 7)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 8)); + position.set(Position.PREFIX_OUT + 3, BitUtil.check(io, 9)); if (header != 0x2626) { - int adcCount = type == MSG_GPS_2 || type == MSG_ALARM_2 ? 5 : 2; - for (int i = 1; i <= adcCount; i++) { + for (int i = 1; i <= 2; i++) { String value = ByteBufUtil.hexDump(buf.readSlice(2)); if (!value.equals("ffff")) { position.set(Position.PREFIX_ADC + i, Integer.parseInt(value) * 0.01); @@ -396,7 +359,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } int alarm = buf.readUnsignedByte(); - position.set(Position.KEY_ALARM, header != 0x2727 ? decodeAlarm1(alarm) : decodeAlarm2(alarm)); + position.set(Position.KEY_ALARM, decodeAlarm(alarm)); if (header != 0x2727) { @@ -510,9 +473,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - if (type == MSG_ALARM || type == MSG_ALARM_2) { - sendResponse(channel, header, type, index, imei, alarm); - } + sendResponse(channel, header, type, index, imei, alarm); return position; } diff --git a/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java b/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java deleted file mode 100644 index 8b9152e8b..000000000 --- a/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java +++ /dev/null @@ -1,44 +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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; - -import java.nio.charset.StandardCharsets; - -public class TechtoCruzFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - int lengthStart = buf.readerIndex() + 3; - int lengthEnd = buf.indexOf(lengthStart, buf.writerIndex(), (byte) ','); - if (lengthEnd > 0) { - int length = lengthStart - + Integer.parseInt(buf.toString(lengthStart, lengthEnd - lengthStart, StandardCharsets.US_ASCII)); - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java deleted file mode 100644 index a217ea738..000000000 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ /dev/null @@ -1,38 +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.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; - -public class TechtoCruzProtocol extends BaseProtocol { - - public TechtoCruzProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TechtoCruzFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TechtoCruzProtocolDecoder(TechtoCruzProtocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java deleted file mode 100644 index 6b9f0edb6..000000000 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java +++ /dev/null @@ -1,108 +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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -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 java.net.SocketAddress; -import java.util.regex.Pattern; - -public class TechtoCruzProtocolDecoder extends BaseProtocolDecoder { - - public TechtoCruzProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$$A") - .number("d+,") // length - .number("(d+),") // imei - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // valid - .expression("[^,]+,") // manufacturer - .expression("([^,]+),") // license plate - .number("(d+.d+),") // speed - .number("(d+),") // odometer - .number("(-?d+.d+),[NS],") // latitude - .number("(-?d+.d+),[WE],") // longitude - .number("(-?d+.d+),") // altitude - .number("(d+.d+),") // course - .number("(d+),") // satellites - .number("(d+),") // rssi - .number("(d+.d+),") // power - .number("(d+.d+),") // battery - .number("([01]),") // charge - .number("[01],") // speed sensor - .number("[01],") // gps status - .number("([01]),") // ignition - .number("([01]),") // overspeed - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN, (String) msg); - 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.setTime(parser.nextDateTime()); - position.setValid(parser.next().equals("A")); - - position.set("registration", parser.next()); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - - position.set(Position.KEY_ODOMETER, parser.nextInt()); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_CHARGE, parser.nextInt() > 0); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); - - if (parser.nextInt() > 0) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } - - return position; - } - -} diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 89ae48b3a..6ba183f9b 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -235,6 +235,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 67: position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); break; + case 69: + position.set("gpsStatus", readValue(buf, length, false)); + break; case 72: case 73: case 74: @@ -255,6 +258,16 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 115: position.set(Position.KEY_COOLANT_TEMP, readValue(buf, length, true) * 0.1); break; + case 129: + case 130: + case 131: + case 132: + case 133: + case 134: + String driver = id == 129 || id == 132 ? "" : position.getString("driver1"); + position.set("driver" + (id >= 132 ? 2 : 1), + driver + buf.readSlice(length).toString(StandardCharsets.US_ASCII).trim()); + break; case 179: position.set(Position.PREFIX_OUT + 1, readValue(buf, length, false) == 1); break; @@ -299,6 +312,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { break; } break; + case 389: + if (BitUtil.between(readValue(buf, length, false), 4, 8) == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); break; diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index d28afbf94..844dd7518 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 Anton Tananaev (anton@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,13 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import org.traccar.model.Command; public class TopinProtocol extends BaseProtocol { public TopinProtocol() { - setSupportedDataCommands( - Command.TYPE_SOS_NUMBER); addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TopinProtocolEncoder(TopinProtocol.this)); pipeline.addLast(new TopinProtocolDecoder(TopinProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 4fe261aa4..87db95946 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -50,11 +50,7 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_STATUS = 0x13; public static final int MSG_WIFI_OFFLINE = 0x17; public static final int MSG_TIME_UPDATE = 0x30; - public static final int MSG_SOS_NUMBER = 0x41; public static final int MSG_WIFI = 0x69; - public static final int MSG_VIBRATION_ON = 0x92; - public static final int MSG_VIBRATION_OFF = 0x93; - public static final int MSG_VIBRATION = 0x94; private void sendResponse(Channel channel, int length, int type, ByteBuf content) { if (channel != null) { @@ -93,19 +89,6 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { return negative ? -result : result; } - private String decodeAlarm(int alarms) { - if (BitUtil.check(alarms, 0)) { - return Position.ALARM_VIBRATION; - } - if (BitUtil.check(alarms, 1)) { - return Position.ALARM_OVERSPEED; - } - if (BitUtil.check(alarms, 4)) { - return Position.ALARM_LOW_POWER; - } - return null; - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -171,7 +154,17 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { if (buf.readableBytes() >= 5) { position.setAltitude(buf.readShort()); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + + int alarms = buf.readUnsignedByte(); + if (BitUtil.check(alarms, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); + } + if (BitUtil.check(alarms, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } + if (BitUtil.check(alarms, 4)) { + position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + } } ByteBuf content = Unpooled.buffer(); @@ -193,12 +186,10 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - ByteBuf content = buf.retainedSlice(buf.readerIndex(), buf.readableBytes() - 2); - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); buf.readUnsignedByte(); // timezone - buf.readUnsignedByte(); // interval + int interval = buf.readUnsignedByte(); if (buf.readableBytes() >= 1 + 2) { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } @@ -212,6 +203,8 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_HEART_RATE, buf.readUnsignedByte()); } + ByteBuf content = Unpooled.buffer(); + content.writeByte(interval); sendResponse(channel, length, type, content); return position; @@ -249,10 +242,6 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); } - if (buf.readableBytes() > 2) { - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - } - position.setNetwork(network); ByteBuf content = Unpooled.buffer(); @@ -261,17 +250,6 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type == MSG_VIBRATION) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); - - return position; - } return null; diff --git a/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java b/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java deleted file mode 100644 index 77f80b9d4..000000000 --- a/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java +++ /dev/null @@ -1,66 +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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import org.traccar.BaseProtocolEncoder; -import org.traccar.Protocol; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class TopinProtocolEncoder extends BaseProtocolEncoder { - - public TopinProtocolEncoder(Protocol protocol) { - super(protocol); - } - - private ByteBuf encodeContent(int type, ByteBuf content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeByte(0x78); - buf.writeByte(0x78); - - buf.writeByte(1 + content.readableBytes()); // message length - - buf.writeByte(type); - - buf.writeBytes(content); - content.release(); - - buf.writeByte('\r'); - buf.writeByte('\n'); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - ByteBuf content = Unpooled.buffer(); - - switch (command.getType()) { - case Command.TYPE_SOS_NUMBER: - content.writeCharSequence(command.getString(Command.KEY_PHONE), StandardCharsets.US_ASCII); - return encodeContent(TopinProtocolDecoder.MSG_SOS_NUMBER, content); - default: - return null; - } - } - -} diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 58c66031e..b5398116d 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -227,22 +227,8 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_GEOFENCE_EXIT; case 0x05: return Position.ALARM_GEOFENCE_ENTER; - case 0x06: - return Position.ALARM_TOW; - case 0x07: - return Position.ALARM_GPS_ANTENNA_CUT; - case 0x10: - return Position.ALARM_POWER_CUT; - case 0x11: - return Position.ALARM_POWER_RESTORED; - case 0x12: - return Position.ALARM_LOW_POWER; - case 0x13: - return Position.ALARM_LOW_BATTERY; case 0x40: - return Position.ALARM_VIBRATION; - case 0x41: - return Position.ALARM_IDLE; + return Position.ALARM_SHOCK; case 0x42: return Position.ALARM_ACCELERATION; case 0x43: @@ -371,11 +357,16 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, BitUtil.check(status, 32 - 4)); position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 5) ? Position.ALARM_GEOFENCE_EXIT : null); position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 6) ? Position.ALARM_GEOFENCE_ENTER : null); - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 7) ? Position.ALARM_GPS_ANTENNA_CUT : null); position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 32 - 9)); position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 32 - 10)); position.set(Position.PREFIX_OUT + 3, BitUtil.check(status, 32 - 11)); - position.set(Position.KEY_STATUS, status); // see https://github.com/traccar/traccar/pull/4762 + position.set(Position.PREFIX_OUT + 4, BitUtil.check(status, 32 - 12)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(status, 32 - 13)); + position.set(Position.PREFIX_IN + 3, BitUtil.check(status, 32 - 14)); + position.set(Position.PREFIX_IN + 4, BitUtil.check(status, 32 - 15)); + position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 16) ? Position.ALARM_SHOCK : null); + position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 18) ? Position.ALARM_LOW_BATTERY : null); + position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 22) ? Position.ALARM_JAMMING : null); position.setTime(parser.nextDateTime()); @@ -470,8 +461,10 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); + String type = null; if (pattern == PATTERN4) { - position.set(Position.KEY_ALARM, decodeAlarm4(parser.nextHexInt())); + type = parser.next(); + position.set(Position.KEY_ALARM, decodeAlarm4(Integer.parseInt(type, 16))); } DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); @@ -492,8 +485,8 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - if (pattern == PATTERN4) { - String response = "$$0014AA" + sentence.substring(sentence.length() - 6, sentence.length() - 2); + if (type != null) { + String response = "$$0014" + type + sentence.substring(sentence.length() - 6, sentence.length() - 2); response += String.format("%02X", Checksum.xor(response)).toUpperCase(); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } else { diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 819c42471..4f6854098 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@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,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.Context; import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; import org.traccar.Protocol; -import org.traccar.config.Keys; -import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; @@ -34,11 +29,6 @@ import org.traccar.model.Network; import org.traccar.model.Position; 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; public class TzoneProtocolDecoder extends BaseProtocolDecoder { @@ -46,20 +36,6 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private void sendResponse(Channel channel, SocketAddress remoteAddress, int index) { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - - String ack = String.format("@ACK,%d#", index); - String time = String.format("@UTC time:%s", dateFormat.format(new Date())); - - ByteBuf response = Unpooled.copiedBuffer(ack + time, StandardCharsets.US_ASCII); - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - private String decodeAlarm(Short value) { switch (value) { case 0x01: @@ -280,28 +256,9 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { int blockLength = buf.readUnsignedShort(); int blockEnd = buf.readerIndex() + blockLength; - if (blockLength > 0) { - if (hardware == 0x10A || hardware == 0x10B || hardware == 0x406) { - - position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); - - } else if (hardware == 0x407) { - - Network network = new Network(); - int count = buf.readUnsignedByte(); - for (int i = 0; i < count; i++) { - buf.readUnsignedByte(); // signal information - - int mcc = BcdUtil.readInteger(buf, 4); - int mnc = BcdUtil.readInteger(buf, 4) % 1000; - - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedInt())); - } - position.setNetwork(network); - - } + if (blockLength > 0 && (hardware == 0x10A || hardware == 0x10B || hardware == 0x406)) { + position.setNetwork(new Network( + CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); } buf.readerIndex(blockEnd); @@ -311,41 +268,25 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { blockLength = buf.readUnsignedShort(); blockEnd = buf.readerIndex() + blockLength; - if (hardware == 0x407 || blockLength >= 13) { + if (blockLength >= 13) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("terminalInfo", buf.readUnsignedByte()); - if (hardware != 0x407) { - int status = buf.readUnsignedByte(); - position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 0)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 1)); - status = buf.readUnsignedByte(); - position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 4)); - if (BitUtil.check(status, 0)) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } + int status = buf.readUnsignedByte(); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 0)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 1)); + status = buf.readUnsignedByte(); + position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 4)); + if (BitUtil.check(status, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); } position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set("gsmStatus", buf.readUnsignedByte()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); - - if (hardware != 0x407) { - position.set(Position.KEY_POWER, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - } else { - int temperature = buf.readUnsignedShort(); - if (!BitUtil.check(temperature, 15)) { - double value = BitUtil.to(temperature, 14) * 0.1; - position.set(Position.PREFIX_TEMP + 1, BitUtil.check(temperature, 14) ? -value : value); - } - int humidity = buf.readUnsignedShort(); - if (!BitUtil.check(humidity, 15)) { - position.set("humidity", BitUtil.to(humidity, 15) * 0.1); - } - position.set("lightSensor", buf.readUnsignedByte() == 0); - } + position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_POWER, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); } if (blockLength >= 15) { @@ -371,10 +312,6 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } - if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { - sendResponse(channel, remoteAddress, buf.getUnsignedShort(buf.writerIndex() - 6)); - } - return position; } diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 4990cfd65..a6b89dde4 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -143,8 +143,8 @@ 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; + int mcc = Integer.parseInt(values[index++]); + int mnc = Integer.parseInt(values[index++]); for (int i = 0; i < cellCount; i++) { network.addCellTower(CellTower.from(mcc, mnc, diff --git a/src/main/java/org/traccar/protocol/Xexun2FrameDecoder.java b/src/main/java/org/traccar/protocol/Xexun2FrameDecoder.java deleted file mode 100644 index 521d0209c..000000000 --- a/src/main/java/org/traccar/protocol/Xexun2FrameDecoder.java +++ /dev/null @@ -1,69 +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.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; -import org.traccar.helper.BufferUtil; - -public class Xexun2FrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 5) { - return null; - } - - ByteBuf flag = Unpooled.wrappedBuffer(new byte[] {(byte) 0xfa, (byte) 0xaf}); - int index; - try { - index = BufferUtil.indexOf(flag, buf, buf.readerIndex() + 2, buf.writerIndex()); - } finally { - flag.release(); - } - - if (index >= 0) { - ByteBuf result = Unpooled.buffer(index + 2 - buf.readerIndex()); - - while (buf.readerIndex() < index + 2) { - int b = buf.readUnsignedByte(); - if (b == 0xfb && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { - buf.readUnsignedByte(); // skip - int ext = buf.readUnsignedByte(); - if (ext == 0x01) { - result.writeByte(0xfa); - result.writeByte(0xaf); - } else if (ext == 0x02) { - result.writeByte(0xfb); - result.writeByte(0xbf); - } - } else { - result.writeByte(b); - } - } - - return result; - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java deleted file mode 100644 index 265841c77..000000000 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ /dev/null @@ -1,34 +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.protocol; - -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class Xexun2Protocol extends BaseProtocol { - - public Xexun2Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Xexun2FrameDecoder()); - pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java deleted file mode 100644 index 766a3f05b..000000000 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ /dev/null @@ -1,205 +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.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.DeviceSession; -import org.traccar.NetworkMessage; -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.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { - - public Xexun2ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - 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.writeByte(0xfa); - response.writeByte(0xaf); - - response.writeShort(type); - response.writeShort(index); - response.writeBytes(imei); - response.writeShort(1); // attributes / length - response.writeShort(0xfffe); // checksum - response.writeByte(1); // response - - response.writeByte(0xfa); - response.writeByte(0xaf); - - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - private String decodeAlarm(long value) { - if (BitUtil.check(value, 0)) { - return Position.ALARM_SOS; - } - if (BitUtil.check(value, 15)) { - return Position.ALARM_FALL_DOWN; - } - return null; - } - - private double convertCoordinate(double value) { - double degrees = Math.floor(value / 100); - double minutes = value - degrees * 100; - return degrees + minutes / 60; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // flag - int type = buf.readUnsignedShort(); - int index = buf.readUnsignedShort(); - - ByteBuf imei = buf.readSlice(8); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, ByteBufUtil.hexDump(imei).substring(0, 15)); - if (deviceSession == null) { - return null; - } - - sendResponse(channel, type, index, imei); - - buf.readUnsignedShort(); // attributes - buf.readUnsignedShort(); // checksum - - if (type == MSG_POSITION) { - List<Integer> lengths = new ArrayList<>(); - List<Position> positions = new ArrayList<>(); - - int count = buf.readUnsignedByte(); - for (int i = 0; i < count; i++) { - lengths.add(buf.readUnsignedShort()); - } - - for (int i = 0; i < count; i++) { - int endIndex = buf.readerIndex() + lengths.get(i); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); - - position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000)); - - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - int battery = buf.readUnsignedShort(); - position.set(Position.KEY_CHARGE, BitUtil.check(battery, 15)); - position.set(Position.KEY_BATTERY_LEVEL, BitUtil.to(battery, 15)); - - int mask = buf.readUnsignedByte(); - - if (BitUtil.check(mask, 0)) { - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); - } - if (BitUtil.check(mask, 1)) { - int positionMask = buf.readUnsignedByte(); - if (BitUtil.check(positionMask, 0)) { - position.setValid(true); - position.setFixTime(position.getDeviceTime()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.setLongitude(convertCoordinate(buf.readFloat())); - position.setLatitude(convertCoordinate(buf.readFloat())); - } - Network network = new Network(); - if (BitUtil.check(positionMask, 1)) { - int wifiCount = buf.readUnsignedByte(); - 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())); - } - } - if (BitUtil.check(positionMask, 2)) { - int cellCount = buf.readUnsignedByte(); - for (int j = 0; j < cellCount; j++) { - network.addCellTower(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readInt(), buf.readUnsignedInt(), buf.readUnsignedByte())); - } - } - if (network.getWifiAccessPoints() != null || network.getCellTowers() != null) { - position.setNetwork(network); - } - if (BitUtil.check(positionMask, 3)) { - buf.skipBytes(12 * buf.readUnsignedByte()); // tof - } - if (BitUtil.check(positionMask, 5)) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.setCourse(buf.readUnsignedShort() * 0.1); - } - if (BitUtil.check(positionMask, 6)) { - position.setValid(true); - position.setFixTime(position.getDeviceTime()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.setLongitude(convertCoordinate(buf.readDouble())); - position.setLatitude(convertCoordinate(buf.readDouble())); - - } - } - if (BitUtil.check(mask, 3)) { - buf.readUnsignedInt(); // fingerprint - } - if (BitUtil.check(mask, 4)) { - buf.skipBytes(20); // version - buf.skipBytes(8); // imsi - buf.skipBytes(10); // iccid - } - if (BitUtil.check(mask, 5)) { - buf.skipBytes(12); // device parameters - } - - if (!position.getValid()) { - getLastLocation(position, position.getDeviceTime()); - } - positions.add(position); - - buf.readerIndex(endIndex); - } - - return positions; - } - - return null; - } - -} |